首页 前端知识 vue | Echarts图表隐藏后变形 宽高问题的解决方案

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

2024-07-24 23:07:39 前端知识 前端哥 721 443 我要收藏

项目中发现,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)
    }
  }
}
转载请注明出处或者链接地址:https://www.qianduange.cn//article/14329.html
标签
评论
发布的文章
大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!