Skip to content

vue2 封装 Echarts

封装共用的 echarts 组件,只需传入 options width height。实现 echarts 组件复用。

App.vue

vue
<template>
  <div>
    <ECharts width="1000px" height="500px" :options="options" />
  </div>
</template>

<script>
import ECharts from '@/components/Echarts'
export default {
  name: 'product',
  components: {
    ECharts
  },
  data() {
    return {
      options: {
        title: {
          text: 'Stacked Line'
        },
        tooltip: {
          trigger: 'axis'
        },
        legend: {
          data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        toolbox: {
          feature: {
            saveAsImage: {}
          }
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            name: 'Email',
            type: 'line',
            stack: 'Total',
            data: [120, 132, 101, 134, 90, 230, 210]
          },
          {
            name: 'Union Ads',
            type: 'line',
            stack: 'Total',
            data: [220, 182, 191, 234, 290, 330, 310]
          },
          {
            name: 'Video Ads',
            type: 'line',
            stack: 'Total',
            data: [150, 232, 201, 154, 190, 330, 410]
          },
          {
            name: 'Direct',
            type: 'line',
            stack: 'Total',
            data: [320, 332, 301, 334, 390, 330, 320]
          },
          {
            name: 'Search Engine',
            type: 'line',
            stack: 'Total',
            data: [820, 932, 901, 934, 1290, 1330, 1320]
          }
        ]
      }
    }
  }
}
</script>

<style scoped>

</style>

Echarts.vue

vue
<template>
  <div :id="nanoid" :style="{width, height}"></div>
</template>

<script>
import { nanoid } from 'nanoid'
import * as echarts from 'echarts'
import { debounce } from 'lodash'

export default {
  name: 'Echarts',
  props: {
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    options: {
      type: Object
    }
  },
  data() {
    return {
      nanoid: nanoid(),
      chart: null
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initCharts()
    })
  },
  watch: {
    options: {
      deep: true,
      handler() {
        this.$nextTick(() => {
          this.initCharts()
        })
      }
    }
  },
  methods: {
    initCharts() {
      if (!document.getElementById(this.nanoid)) return
      this.chart = echarts.init(document.getElementById(this.nanoid))
      this.chart.setOption(this.options)
      // 引入debounce,防止频繁更改浏览页尺寸出现页面抖动
      window.addEventListener('resize', debounce(() => {
        if (this.chart) {
          this.chart.resize()
        }
      }, 100))
    }
  },
  // 组件销毁 echarts 销毁
  beforeDestroy() {
    if (!this.chart) {
      return;
    }
    this.chart.dispose();
    this.chart = null;
  }
}
</script>

<style scoped>

</style>

Released under the MIT License.