项目中发现,echarts图表在v-if隐藏之后再出现,宽高会变成100px,如下图:

其原因是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) } } }
复制