今天在处理echarts还遇到一个问题,就是在父组件异步请求拿到数据前,想要默认显示占位图并隐藏图表,但是出现了如题问题
开始是使用v-if进行处理,但是渲染报错,提示:Initialize failed: invalid dom【初始化失败:无效的dom】,说明图表渲染的时候,这个dom不存在,但是换成v-show的话就可以展示出来图表。然后看了下官方文档的关于v-if和v-show的区别,如下所示:
由上述看目前只能使用v-show,但是v-show展示图表的时候出现了标题的问题,图表的大小一直为100px,可能是因为渲染时图表的被隐藏了,JS方法初始化时就无法获取父元素的宽度,图表就默认展示100px
其实这个问题原因就是JS方法初始化时,图表被隐藏了,所以我们是可以使用$nextTick来处理这个问题,这个是官方对其介绍:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
下面是处理程序:
<template>
<div class="ChartBasicLine">
<div class="chart_content">
// 图表
<div v-if="isShow" class="chart_display">
<div
:ref="chartObj.type"
class="chart_show"
/>
</div>
// 初始化这展示占位图
<img src="@/assets/common/no_data.png" class="chart_no_data" v-if="!isShow">
</div>
</div>
</template>
<script>
export default {
name: 'ChartBasicLine',
props: {
chartObj: {
type: Object
}
},
data() {
return {
isShow: false,
option: {
tooltip: {
trigger: 'axis'
},
grid: {
top: '22px',
left: '40px',
right: '30px',
bottom: '30px'
},
xAxis: {
boundaryGap: false,
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#999999'
}
},
axisLabel: {
fontSize: 10
}
},
yAxis: {
type: 'value'
},
series: [{
type: 'line'
}]
},
myChart: {
}
}
},
watch: {
chartObj: {
// 监控数据的变化,并刷新图表
handler(newVal, oldVal) {
this.chartObj = newVal
this.showChart()
},
deep: true
}
},
mounted() {
this.showChart()
},
methods: {
showChart() {
if (this.chartObj.xData.length === 0) {
return
}
// 展示图表
this.isShow = true
// 数据更新后,然后再渲染图表
this.$nextTick(() => {
this.myChart = this.$echarts.init(this.$refs[this.chartObj.type])
this.option.xAxis['data'] = this.chartObj.xData
this.option.series[0]['data'] = this.chartObj.yData
this.myChart.setOption(this.option)
})
}
}
}
</script>
当父组件异步请求获取数据后,使用$nextTick来初始化图表,将渲染时初始化图表改成数据更新后初始化图表,这时视图中的元素被展示了,所以使用v-if和v-show都行。