Echarts 组件封装(Vue2 版)

Echarts 组件封装(Vue2 版)

一、环境安装

执行命令安装项目依赖

npm install echarts element-resize-detector lodash --save

二、全局引入 Echarts

1. 创建 Echarts 配置文件

路径:src/echarts.js

import Vue from 'vue'

// 引入ECharts 主模块
let echarts = require('echarts/lib/echarts')
// 引入ECharts 主题
require('echarts/theme/macarons')

// 引入折线图、柱状图、饼图等图表
require('echarts/lib/chart/line')
require('echarts/lib/chart/pie')
require('echarts/lib/chart/bar')

// 引入各类组件
require('echarts/lib/component/axisPointer')
require('echarts/lib/component/brush')
require('echarts/lib/component/calendar')
require('echarts/lib/component/dataset')
require('echarts/lib/component/dataZoom')
require('echarts/lib/component/dataZoomInside')
require('echarts/lib/component/dataZoomSelect')
require('echarts/lib/component/dataZoomSlider')
require('echarts/lib/component/geo')
require('echarts/lib/component/graphic')
require('echarts/lib/component/grid')
require('echarts/lib/component/gridSimple')
require('echarts/lib/component/legend')
require('echarts/lib/component/legendScroll')
require('echarts/lib/component/markArea')
require('echarts/lib/component/markLine')
require('echarts/lib/component/markPoint')
require('echarts/lib/component/parallel')
require('echarts/lib/component/polar')
require('echarts/lib/component/radar')
require('echarts/lib/component/singleAxis')
require('echarts/lib/component/timeline')
require('echarts/lib/component/title')
require('echarts/lib/component/toolbox')
require('echarts/lib/component/tooltip')
require('echarts/lib/component/visualMap')
require('echarts/lib/component/visualMapContinuous')
require('echarts/lib/component/visualMapPiecewise')

// 挂载到 Vue 实例
Vue.prototype.$echarts = echarts

2. 在入口文件引入

路径:src/main.js

// 引入 Echarts 全局配置
import "@/echarts"

三、封装 Echarts 通用组件

1. 组件目录

组件路径:src/components/Echarts/index.vue

2. 组件完整代码

<template>
  <div :ref="echarts" class="echarts"></div>
</template>

<script>
import elementResizeDetectorMaker from 'element-resize-detector'
import _ from 'lodash'

export default {
  name: 'Echarts',
  props: {
    // 配置项
    echartsConfig: {
      prop: Object,
      required: true,
      default: () => {
      }
    }
  },
  data() {
    return {
      // 图表实例
      generalChart: null,
      echarts: _.uniqueId('echarts_')
    }
  },
  watch: {
    echartsConfig: {
      deep: true,
      handler(val) {
        this.updateCharts()
      }
    }
  },
  mounted() {
    this.initChart()
  },
  methods: {
    initChart() {
      this.$nextTick(() => {
        let generalChart = this.generalChart
        // 初始化图表
        generalChart = this.$echarts.init(this.$refs[this.echarts], 'macarons')
        // 重新计算渲染区域大小
        generalChart.resize()
        // 初始化配置
        generalChart.setOption(this.echartsConfig)
        // 监听窗口大小变化事件
        const resizeObserver = new ResizeObserver(entries => {
          // entries 是一个 ResizeObserverEntry 对象数组,包含目标元素的大小信息
          for (const entry of entries) {
            const { width, height } = entry.contentRect;
            // 根据外部盒子的宽度来设置echarts图的宽度
            generalChart.resize({ width, height });
          }
        })
        // 开始监听最外层的 resizeTarget 元素的大小变化
        const resizeTarget = this.$refs[this.echarts];
        resizeObserver.observe(resizeTarget);

        // 在组件销毁时停止监听,防止内存泄漏
        this.$once('hook:beforeDestroy', () => {
          resizeObserver.disconnect();
        })
      })
    },
    updateCharts() {
      let generalChart = this.generalChart
      // 每次初始化前移除之前的图表属性
      this.$refs[this.echarts].removeAttribute('_echarts_instance_')
      // 初始化图表
      generalChart = this.$echarts.init(this.$refs[this.echarts], 'macarons')
      // 重新计算渲染区域大小
      generalChart.resize()
      // 清理缓存
      generalChart.clear()
      // 初始化配置
      generalChart.setOption(this.echartsConfig)
      // 监听窗口大小变化事件
      const resizeObserver = new ResizeObserver(entries => {
        // entries 是一个 ResizeObserverEntry 对象数组,包含目标元素的大小信息
        for (const entry of entries) {
          const { width, height } = entry.contentRect;
          // 根据外部盒子的宽度来设置echarts图的宽度
          generalChart.resize({ width, height });
        }
      })
      // 开始监听最外层的 resizeTarget 元素的大小变化
      const resizeTarget = this.$refs[this.echarts];
      resizeObserver.observe(resizeTarget);

      // 在组件销毁时停止监听,防止内存泄漏
      this.$once('hook:beforeDestroy', () => {
        resizeObserver.disconnect();
      })
    }
  }
}
</script>

<style>
.echarts {
  width: 100%;
  height: 100%;
}
</style>

四、全局注册组件

src/main.js 中添加组件全局注册代码

// 引入 Echarts 组件
import Echarts from "@/components/Echarts"
// 全局注册
Vue.component('Echarts', Echarts)

五、组件使用示例

页面中使用

<template>
  <div class="chart-wrap">
    <Echarts :echarts-config="chartOption" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      chartOption: {
        title: {
          text: '柱状图示例'
        },
        xAxis: {
          type: 'category',
          data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            data: [120, 200, 150, 80, 70, 110, 130],
            type: 'bar'
          }
        ]
      }
    }
  }
}
</script>

<style scoped>
.chart-wrap {
  width: 600px;
  height: 400px;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值