项目中发现,echarts图表在v-if隐藏之后再出现,宽高会变成100px,如下图:
![](https://www.qianduange.cn/upload/article/31a0682bf98c36488c924da5cb8d8a68.png)
其原因是Echarts在初始化实例的时候,对应dom元素的宽高还没有确定。
一开始使用了其他博主的方案:
监听对应dom元素,如果大小发生变化,调用resize()方法。如下:
this.chart = echarts.init(this.$refs.barChart)
// 图像随屏幕大小改变而改变
window.addEventListener('resize', () => {
if (this.chart) {
this.$nextTick(() => {
this.chart.resize()
})
}
})
// 解决图表变形,若dom尺寸发生变化则resize (方法一)
const chartObserver = new ResizeObserver(() => {
if (this.chart) {
this.$nextTick(() => {
this.chart.resize()
})
}
});
chartObserver.observe(this.$refs.barChart);
但是发现,图表隐藏后再显示,虽然宽高是正确的,但是echarts动画效果消失。
并且我在数据更新后有执行清除动画clear,如下:
initEcharts (data) {
this.chart.clear()
const baseOptions = cloneDeep(echartsOptions.baseOptions)
const options = merge(baseOptions, data)
this.chart.setOption(options)
},
寻找方法无果后发现,不使用上面的'方法一',改用方法二:
watch: {
chartOptions: {
deep: true,
handler (data) {
this.noDataFlag = data.noData
this.noAuthorityFlag = data.noAuthority
this.pleaseParentNodeFlag = data.pleaseParentNodeFlag
if (!this.noDataFlag && !this.noAuthority && !this.pleaseParentNodeFlag) {
this.$nextTick(() => {
this.chart.resize() // 方法二
this.initEcharts(data)
})
}
}
}
},
在数据更新方法前执行resize()方法,即解决宽高变成100px的问题,并且不会丢失动画效果。
如有更好的方法,欢迎讨论和指教。
附代码(组件形式):
html:
<template>
<div class="w-full h-full">
<div v-show="!noDataFlag" ref="barChart" class="chart w-full h-full"></div>
<no-data v-if="noDataFlag"></no-data>
</div>
</template>
js:
import NoData from './NoData'
import { merge, cloneDeep } from 'lodash'
import * as echarts from 'echarts'
import { echartsOptions } from '@/utils/setting'
export default {
// 部分略
props: {
chartOptions: {
type: Object,
default () {
return {}
}
}
},
data () {
return {
chart: null,
noDataFlag: false,
}
},
watch: {
chartOptions: {
deep: true,
handler (data) {
this.noDataFlag = data.noData
if (!this.noDataFlag) {
this.$nextTick(() => {
this.chart.resize()
this.initEcharts(data)
})
}
}
}
},
mounted () {
this.chart = echarts.init(this.$refs.barChart)
// 图像随屏幕大小改变而改变
window.addEventListener('resize', () => {
if (this.chart) {
this.$nextTick(() => {
this.chart.resize()
})
}
})
// 解决图表变形,若dom尺寸发生变化则resize
// const chartObserver = new ResizeObserver(() => {
// if (this.chart) {
// this.$nextTick(() => {
// console.log(2);
// this.chart.resize()
// })
// }
// });
// chartObserver.observe(this.$refs.barChart);
},
methods: {
initEcharts (data) {
this.chart.clear()
const baseOptions = cloneDeep(echartsOptions.baseOptions)
const options = merge(baseOptions, data)
this.chart.setOption(options)
}
}
}