vue組件中watch props根據(jù)v-if動態(tài)判斷并掛載DOM的問題
問題復(fù)現(xiàn):父組件中通過名為 source 的 prop 向子組件 Chart 傳入數(shù)據(jù)
<Chart :source="chartData"></Chart>
import Chart from '../components/Chart'
export default {
name: 'Home',
components: { Chart },
data () {
return {
chartData: []
}
},
mounted () {
setTimeout(() => {
this.chartData = [
[89.3, 58212, 'Matcha Latte'],
[57.1, 78254, 'Milk Tea'],
[74.4, 41032, 'Cheese Cocoa'],
[50.1, 12755, 'Cheese Brownie'],
[89.7, 20145, 'Matcha Cocoa'],
[68.1, 79146, 'Tea'],
[19.6, 91852, 'Orange Juice'],
[10.6, 101852, 'Lemon Juice'],
[32.7, 20112, 'Walnut Brownie']
]
}, 2000)
}
}
子組件接收 source 數(shù)據(jù)當(dāng)存在且至少有一條數(shù)據(jù)的時候,創(chuàng)建 id 為 main 的 div,用以初始化 echarts 實(shí)例
<div v-if="source && source.length" id="main" ref="main" style="width: 600px;height: 400px;"></div> <div vi-else>none</div>
Chart 組件通過接收數(shù)據(jù) watch prop 的變化動態(tài)的調(diào)用 echarts 的 setOptions 方法,最終渲染數(shù)據(jù)。
export default {
// ...
watch: {
source (newVal, oldVal) {
this.setOpts()
}
},
props: ['source'],
methods: {
setOpts () {
let myChart = this.$echarts.init(this.$refs.main)
myChart.setOption({
dataset: {
// ...
source: this.source
},
// ...
})
}
}
}
如果直接這么寫必定報錯:
Error in callback for watcher "source": "TypeError: Cannot read property 'getAttribute' of undefined"
在代碼中增加一行代碼:
watch: {
source (newVal, oldVal) {
console.log(newVal, this.$refs.main) // [Array ...] undefined
this.setOpts()
}
},
啟示 source 數(shù)據(jù)雖然有了,但 div 還并未掛載,因此 echarts 無法完成初始化
那么想當(dāng)然的我們就會去在 mounted 生命周期函數(shù)中調(diào)用 setOpts 方法:
mounted () {
console.log(this.source, this.$refs.main) // [] undefined
this.setOpts()
},
這樣也是錯的,因?yàn)槟0逭Z法中使用了 v-if,那么當(dāng) source 并未滿足條件的時候,div 當(dāng)然也不會掛載。因此 div 仍然無法訪問到。
Error in mounted hook: "TypeError: Cannot read property 'getAttribute' of undefined"
解決辦法是要么去掉 v-if 要么換另一種寫法
有時我們需要在沒有數(shù)據(jù)的情況下增加一個占位標(biāo)簽用來展示一些額外的提醒信息,如“暫未獲取到數(shù)據(jù)”等。那么去掉 v-if 肯定不行。
既然如此我們保留 v-if 但寫法有所改變:
修改 Chart 組件:
<template> <div> <div id="main" ref="main" style="width: 600px;height: 400px;"></div> </div> </template>
我們只需要一個 source 數(shù)據(jù)源,當(dāng) mounted 的時候調(diào)用 setOpts 方法,當(dāng) watch 數(shù)據(jù)變化的時候再次調(diào)用以更新數(shù)據(jù)
export default {
name: 'Chart',
props: ['source'],
mounted () {
this.setOpts()
},
watch: {
source () {
this.setOpts()
}
},
methods: {
setOpts () {
let myChart = this.$echarts.init(this.$refs.main)
myChart.setOption({
dataset: {
dimensions: ['score', 'amount', 'product'],
source: this.source
},
xAxis: { type: 'category' },
yAxis: {},
series: [
{
type: 'bar',
encode: {
x: 'product',
y: 'amount'
}
}
]
})
}
}
}
v-if 的判斷我們把他移出去了我們判斷 chartData 是否獲取到,一旦獲取到數(shù)據(jù),馬上加載 Chart 組件,這樣就可以避開在組件內(nèi)部調(diào)用 v-if 帶來的問題:
<template>
<div>
<Chart :source="chartData" v-if="flag"></Chart>
<div v-else>none</div>
</div>
</template>
import Chart from '../components/Chart'
export default {
name: 'Home',
components: { Chart },
data () {
return {
chartData: [],
flag: false
}
},
methods: {
getData () {
setTimeout(() => {
this.chartData = [
[89.3, 58212, 'Matcha Latte'],
[57.1, 78254, 'Milk Tea'],
[74.4, 41032, 'Cheese Cocoa'],
[50.1, 12755, 'Cheese Brownie'],
[89.7, 20145, 'Matcha Cocoa'],
[68.1, 79146, 'Tea'],
[19.6, 91852, 'Orange Juice'],
[10.6, 101852, 'Lemon Juice'],
[32.7, 20112, 'Walnut Brownie']
]
this.flag = true
}, 2000)
}
},
mounted () {
this.getData()
}
}
另外還可將 Chart 組件和站位標(biāo)簽一同封裝成一個 ChartWrapper。
這樣就不會因在組件內(nèi)部調(diào)用 watch 監(jiān)聽 props 的變化動態(tài) v-if 判斷并掛載數(shù)據(jù)到 DOM 上出現(xiàn)的這種問題了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解CocosCreator項(xiàng)目結(jié)構(gòu)機(jī)制
這篇文章主要介紹了詳解CocosCreator項(xiàng)目結(jié)構(gòu)機(jī)制,只有了解這些機(jī)制后,才能更好的進(jìn)行項(xiàng)目開發(fā),避免潛在錯誤,并且快速的除錯2021-04-04
javascript 三種數(shù)組復(fù)制方法的性能對比
javascript 三種數(shù)組復(fù)制方法的性能對比,對于webkit, 使用concat; 其他瀏覽器, 使用slice.2010-01-01
JavaScript中關(guān)鍵字 in 的使用方法詳解
這篇文章主要介紹了JavaScript中關(guān)鍵字 in 的使用方法詳解,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-10-10
基于leaflet.js實(shí)現(xiàn)修改地圖主題樣式的流程分析
這篇文章主要介紹了基于leaflet.js實(shí)現(xiàn)修改地圖主題樣式的流程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
layui清空,重置表單數(shù)據(jù)的實(shí)例
今天小編就為大家分享一篇layui清空,重置表單數(shù)據(jù)的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09

