Vue2封装Echarts

使用方法:

1、模版使用

<Echarts :option="chartOption" />
2、导入组件
import Echarts from '@/components/Echarts'
3、配置option
chartOption: {
        title: {
          text: '员工学历分布',
          left: 'left',
          textStyle: {
            color: '#333',
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        xAxis: {
          type: 'category',
          data: []
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            data: [],
            type: 'bar'
          }
        ]
      }

4、接口拿到数据赋值

async getAnalysisEducationQuery() {
      let educationQuery = await analysisEducationQuery({})
      let category = []
      let data = []
      educationQuery.data.forEach(el => {
        category.push(el.name)
        data.push(el.number)
      });
      this.chartOption.xAxis.data = category
      this.chartOption.series[0].data = data
      this.loading = false
    },

 

 

 

组件代码:

<template>
  <div ref="chartContainer" class="chart-container" :style="{ width: width, height: height }"></div>
</template>

<script>
import echarts from 'echarts';

export default {
  name: 'ECharts',
  props: {
    option: {
      type: Object,
      required: true
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '400px'
    },
    autoResize: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      myChart: null,
      resizeObserver: null
    };
  },
  mounted() {
    this.initChart();
    this.observeResize();
  },
  beforeDestroy() {
    this.cleanup();
  },
  watch: {
    // 监听 option 变化,更新图表
    option: {
      handler(newOption) {
        this.updateChart(newOption);
      },
      deep: true
    },
    // 监听宽高变化,重绘图表
    width() {
      this.resizeChart();
    },
    height() {
      this.resizeChart();
    }
  },
  methods: {
    // 初始化图表
    initChart() {
      if (!this.$refs.chartContainer) return;

      // 销毁旧实例(避免内存泄漏)
      if (this.myChart) {
        this.myChart.dispose();
      }

      // 创建新实例
      this.myChart = echarts.init(this.$refs.chartContainer);
      this.myChart.setOption(this.option);

      // 初始自适应
      this.resizeChart();
    },

    // 更新图表配置
    updateChart(newOption) {
      if (this.myChart) {
        this.myChart.setOption(newOption);
      }
    },

    // 重绘图表
    resizeChart() {
      if (this.myChart) {
        this.myChart.resize();
      }
    },

    // 监听容器尺寸变化
    observeResize() {
      if (!this.autoResize || !this.$refs.chartContainer) return;

      // 检查浏览器是否支持 ResizeObserver
      if ('ResizeObserver' in window) {
        // 使用 ResizeObserver 监听容器尺寸变化
        this.resizeObserver = new ResizeObserver(() => {
          this.resizeChart();
        });

        this.resizeObserver.observe(this.$refs.chartContainer);
      }

      // 监听窗口缩放
      window.addEventListener('resize', this.resizeChart);
    },

    // 清理监听器
    cleanup() {
      if (this.resizeObserver) {
        this.resizeObserver.disconnect();
        this.resizeObserver = null;
      }

      window.removeEventListener('resize', this.resizeChart);

      if (this.myChart) {
        this.myChart.dispose();
        this.myChart = null;
      }
    }
  }
};
</script>

<style scoped>
.chart-container {
  width: 100%;
  height: 100%;
  min-width: 300px;
  /* 防止图表过小时布局异常 */
}
</style>

 

posted @ 2025-08-07 17:10  蜗牛snail  阅读(15)  评论(0)    收藏  举报
蜗牛前端 蜗牛文学