vue | Echarts图表隐藏后变形 宽高问题的解决方案

项目中发现,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)
    }
  }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值