The Watch props dynamically determines and mounts DOM problems based on v-IF
⭐️ more front-end technology and knowledge, search subscription number JS bacteria subscription
Problem reappears: Data is passed from the parent component to the child component Chart via prop named Source
<Chart :source="chartData"></Chart>
Copy the code
import Chart from '.. /components/Chart'
export default {
name: 'Home'.components: { Chart },
data () {
return {
chartData: []
}
},
mounted () {
setTimeout((a)= > {
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)}}Copy the code
When there is at least one source data, create a div with id main to initialize the echarts instance
<div v-if="source && source.length" id="main" ref="main" style="width: 600px; height: 400px;"></div>
<div vi-else>none</div>
Copy the code
Chart component dynamically calls The setOptions method of Echarts by receiving the change of data Watch Prop, and finally renders the data.
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
},
// ...})}}}Copy the code
If you write this directly, you will get an error:
Error in callback for watcher “source”: “TypeError: Cannot read property ‘getAttribute’ of undefined”
Add a line to the code:
watch: {
source (newVal, oldVal) {
console.log(newVal, this.$refs.main) // [Array ...] undefined
this.setOpts()
}
},
Copy the code
The revelation source data is available, but the div is not yet mounted, so Echarts cannot complete initialization
/ / setOpts (mounted); / / setOpts (mounted); / / setOpts (mounted);
mounted () {
console.log(this.source, this.$refs.main) // [] undefined
this.setOpts()
},
Copy the code
This is also wrong because the template syntax uses v-if, so div will not be mounted if the source does not meet the criteria. So div is still not accessible.
Error in mounted hook: “TypeError: Cannot read property ‘getAttribute’ of undefined”
The solution is to either drop the V-if or write it differently
Sometimes we need to add a placeholder label to display additional reminders when there is no data available, such as “data not available yet”. So you can’t get rid of v minus if.
In this case we keep the v-if but write it differently:
Modify Chart component:
<template> <div> <div id="main" ref="main" style="width: 600px; height: 400px;" ></div> </div> </template>Copy the code
When Mounted, call setOpts. When watch changes, call setOpts to update data
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'}}]})}}Copy the code
As soon as chartData is retrieved, load the Chart component immediately. This avoids the problem of calling v-if inside the component:
<template>
<div>
<Chart :source="chartData" v-if="flag"></Chart>
<div v-else>none</div>
</div>
</template>
Copy the code
import Chart from '.. /components/Chart'
export default {
name: 'Home'.components: { Chart },
data () {
return {
chartData: [].flag: false}},methods: {
getData () {
setTimeout((a)= > {
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()
}
}
Copy the code
In addition, the Chart component and the station tag can be encapsulated as a ChartWrapper.
This avoids the problem of dynamic V-if judging and mounting data to the DOM due to changes in the call to the watch listening props inside the component.
Please pay attention to my subscription number, push technical articles about JS irregularly, only talk about technology not gossip 😊