小編給大家分享一下vue組件中如何解決watch props根據(jù)v-if動態(tài)判斷并掛載DOM的問題,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
為云城等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及云城網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為成都網(wǎng)站設計、成都做網(wǎng)站、云城網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
問題復現(xiàn):父組件中通過名為 source 的 prop 向子組件 Chart 傳入數(shù)據(jù)
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ù)當存在且至少有一條數(shù)據(jù)的時候,創(chuàng)建 id 為 main 的 div,用以初始化 echarts 實例
none
Chart 組件通過接收數(shù)據(jù) watch prop 的變化動態(tài)的調用 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 無法完成初始化
那么想當然的我們就會去在 mounted 生命周期函數(shù)中調用 setOpts 方法:
mounted () { console.log(this.source, this.$refs.main) // [] undefined this.setOpts() },
這樣也是錯的,因為模板語法中使用了 v-if,那么當 source 并未滿足條件的時候,div 當然也不會掛載。因此 div 仍然無法訪問到。
Error in mounted hook: "TypeError: Cannot read property 'getAttribute' of undefined"
解決辦法是要么去掉 v-if 要么換另一種寫法
有時我們需要在沒有數(shù)據(jù)的情況下增加一個占位標簽用來展示一些額外的提醒信息,如“暫未獲取到數(shù)據(jù)”等。那么去掉 v-if 肯定不行。
既然如此我們保留 v-if 但寫法有所改變:
修改 Chart 組件:
我們只需要一個 source 數(shù)據(jù)源,當 mounted 的時候調用 setOpts 方法,當 watch 數(shù)據(jù)變化的時候再次調用以更新數(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 組件,這樣就可以避開在組件內部調用 v-if 帶來的問題:
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() } } none
另外還可將 Chart 組件和站位標簽一同封裝成一個 ChartWrapper。
這樣就不會因在組件內部調用 watch 監(jiān)聽 props 的變化動態(tài) v-if 判斷并掛載數(shù)據(jù)到 DOM 上出現(xiàn)的這種問題了。
看完了這篇文章,相信你對“vue組件中如何解決watch props根據(jù)v-if動態(tài)判斷并掛載DOM的問題”有了一定的了解,如果想了解更多相關知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!