vue引用echarts

0 阅读1分钟

一、引入ECharts到Vue项目的三种方式

1. 全局引入(适合项目频繁使用)

// main.js
import Vue from 'vue';
import * as echarts from 'echarts';

Vue.prototype.$echarts = echarts; // 挂载到Vue原型,全局可用
  • 使用示例
    export default {
      mounted() {
        const chart = this.$echarts.init(this.$refs.chartContainer);
        chart.setOption(option);
      }
    }
    

2. 局部引入(按需加载,推荐)

<template>
  <div ref="chartContainer" style="width: 100%; height: 400px;"></div>
</template>

<script>
import * as echarts from 'echarts'; // 局部引入

export default {
  mounted() {
    const chart = echarts.init(this.$refs.chartContainer);
    chart.setOption(option);
  }
}
</script>

3. 按需引入(体积优化)

// 仅引入必要模块(如折线图、柱状图)
import echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/line';
import 'echarts/lib/chart/bar';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/legend';

二、封装ECharts组件(可复用方案)

基础组件封装

// ECharts.vue
<template>
  <div ref="chartRef" :style="{ width, height }"></div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  props: {
    option: { type: Object, required: true },
    width: { type: String, default: '100%' },
    height: { type: String, default: '400px' }
  },
  data() {
    return {
      chart: null
    };
  },
  mounted() {
    this.initChart();
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$refs.chartRef);
      this.chart.setOption(this.option);
      
      // 监听窗口大小变化,自适应图表
      window.addEventListener('resize', this.resizeChart);
    },
    resizeChart() {
      this.chart && this.chart.resize();
    }
  },
  watch: {
    option: {
      deep: true,
      handler(newVal) {
        this.chart && this.chart.setOption(newVal);
      }
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeChart);
    this.chart && this.chart.dispose(); // 销毁图表释放资源
  }
};
</script>

使用封装组件

<template>
  <div>
    <ECharts :option="chartOption" />
  </div>
</template>

<script>
import ECharts from '@/components/ECharts.vue';

export default {
  components: { ECharts },
  data() {
    return {
      chartOption: {
        xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed'] },
        yAxis: { type: 'value' },
        series: [{ data: [820, 932, 901], type: 'bar' }]
      }
    };
  }
};
</script>

三、Vue3组合式API(Composition API)用法

<template>
  <div ref="chartRef" style="width: 100%; height: 400px;"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import * as echarts from 'echarts';

const chartRef = ref(null);
const chart = ref(null);
const props = defineProps({
  option: { type: Object, required: true }
});

const initChart = () => {
  chart.value = echarts.init(chartRef.value);
  chart.value.setOption(props.option);
  
  const resizeHandler = () => {
    chart.value && chart.value.resize();
  };
  
  window.addEventListener('resize', resizeHandler);
  
  // 保存到ref以便在unmount时移除监听
  chartRef.value.resizeHandler = resizeHandler;
};

onMounted(() => {
  initChart();
});

watch(
  () => props.option,
  (newVal) => {
    chart.value && chart.value.setOption(newVal);
  },
  { deep: true }
);

onUnmounted(() => {
  if (chartRef.value.resizeHandler) {
    window.removeEventListener('resize', chartRef.value.resizeHandler);
  }
  chart.value && chart.value.dispose();
});
</script>

四、性能优化与注意事项

1. 避免重复渲染

// 使用v-if控制图表渲染时机
<template>
  <div v-if="showChart">
    <ECharts :option="chartOption" />
  </div>
</template>

2. 按需加载主题

import darkTheme from 'echarts/theme/dark';

// 注册主题后使用
echarts.registerTheme('dark', darkTheme);
const chart = echarts.init(this.$refs.chartContainer, 'dark');

3. 处理大数据量

// 使用增量渲染(适合实时数据流)
chart.setOption({
  series: [{
    type: 'line',
    progressive: 1000, // 每屏渲染的数据点数量
    data: largeDataArray
  }]
});

五、问题

1. 问:Vue中ECharts的生命周期管理要点?

    • mounted:初始化图表并设置option;
    • watch:监听option变化,动态更新图表;
    • beforeDestroy/beforeUnmount:移除resize监听,销毁图表实例释放内存。

2. 问:如何优化ECharts在Vue中的性能?

    • 按需引入ECharts模块,减小打包体积;
    • 使用v-if控制非必要图表渲染;
    • 大数据场景启用progressivedataZoom
    • 窗口resize时使用节流函数(如lodash.throttle)避免频繁重绘。

3. 问:ECharts组件如何响应父组件数据变化?

    • 通过watch监听props变化,调用chart.setOption(newVal)更新图表;
    • 若数据量庞大,可通过chart.setOption(newVal, true)强制清空并重绘。

六、总结

  1. 引入方式:优先局部引入,按需加载模块;
  2. 组件封装:将ECharts封装为可复用组件,管理好生命周期;
  3. 响应式处理:监听窗口resize并调用chart.resize()
  4. 性能优化:避免重复渲染,合理配置ECharts参数。