笔记--vue2中使用echarts模板

29 阅读1分钟
<template>
  <div class="content_body" ref="chartContainer">
  </div>
</template>

<script>
import * as echarts from 'echarts'
import { ResizeObserverHelper } from '@/module/util/resizeObserverHelper.js';
const color = ['#6b7585', '#1de9b6', '#40fdce', '#885BD2', '#B6D8F3']
export default {
  data () {
    return {
      chart: null,
      observer: null,
    }
  },

  watch: {

  },
  mounted () {
    this.updateChartData()
  },
  beforeMount () {
    if (this.chart) {
      this.chart.dispose(); // 销毁图表实例
      this.chart = null; // 清空引用
    }
    this.observer && this.observer.disconnect(); // 断开监听
  },
  methods: {
    initChart (newData) {
      try {
        this.chart = echarts.init(this.$refs.chartContainer);
        this.updateChartData(newData)
        // 开启监听
        this.observer = new ResizeObserverHelper(this.$refs.chartContainer, (width, height) => {
          this.chart && this.chart.resize(); // 手动调整 ECharts
        });
      } catch (error) {
      }
    },
    updateChartData (newData) {
      if (!this.chart) {
        this.$nextTick(() => {
          this.initChart(newData);
        });
        return;
      }

      this.chart.setOption(/* 配置 /)
       
    }
  },
}
</script>
<style lang="scss" scoped>
.content_body {
  height: 100%;
}
</style>
// resizeObserverHelper.js
/**
 * 监听 DOM 元素或 window 尺寸变化的工具类
 * @example
 * const observer = new ResizeObserverHelper(element, (width, height) => {
 *   console.log('尺寸变化:', width, height);
 *   chart.resize(); // 手动调整 ECharts
 * });
 * 
 * // 销毁监听
 * observer.disconnect();
 */
export class ResizeObserverHelper {
  /**
   * @param {HTMLElement|Window|string} target 监听的 DOM 元素、window 或 CSS 选择器
   * @param {(width: number, height: number) => void} callback 尺寸变化时的回调
   * @param {number} debounceDelay 防抖延迟(毫秒,默认 200)
   */
  constructor(target, callback, debounceDelay = 200) {
    this.target = typeof target === 'string' ? document.querySelector(target) : target;
    this.callback = callback;
    this.debounceDelay = debounceDelay;
    this.debounceTimer = null;
    this.resizeObserver = null;

    this.init();
  }

  init() {
    // 监听 window 变化
    if (this.target === window) {
      this.handleWindowResize();
      return;
    }

    // 监听 DOM 元素变化
    if (this.target instanceof HTMLElement) {
      this.handleElementResize();
      return;
    }

    throw new Error('Invalid target: must be HTMLElement, window, or CSS selector');
  }

  // 监听 window 的 resize 事件
  handleWindowResize() {
    const handler = () => {
      this.debouncedCallback(window.innerWidth, window.innerHeight);
    };
    window.addEventListener('resize', handler);
    this.disconnect = () => window.removeEventListener('resize', handler);
    handler(); // 初始触发一次
  }

  // 监听 DOM 元素的 ResizeObserver
  handleElementResize() {
    this.resizeObserver = new ResizeObserver((entries) => {
      const { width, height } = entries[0].contentRect;
      this.debouncedCallback(width, height);
    });
    this.resizeObserver.observe(this.target);
    this.disconnect = () => this.resizeObserver.disconnect();
  }

  // 防抖回调
  debouncedCallback = (width, height) => {
    clearTimeout(this.debounceTimer);
    this.debounceTimer = setTimeout(() => {
      this.callback(width, height);
    }, this.debounceDelay);
  };

  // 销毁监听
  disconnect() {
    if (this.disconnect) this.disconnect();
    clearTimeout(this.debounceTimer);
  }
}