封装一个vue2版本的echarts基础组件

前言

看到公司小伙伴在vue项目中用到echarts显示图表,都是在当前组件内直接引入echarts,然后书写一堆配置,这样会存在一些问题。

如果项目内多处需要显示图表,每次都需要引入echarts,然后初始化,再处理数据和图表容器大小变化,确实有些繁琐,其实我们都在使用vue了,完成可以封装一个基础图表组件,后面使用的时候,直接传入关于图表的配置就可以了。

基础图表组件

  • 安装echarts:npm i echarts
  • 安装元素大小调整监听器:npm i elementResizeDetectorMaker
xml 复制代码
<template>
  <div id="chart" ref="chart" :style="style"></div>
</template>

<script>
import * as echarts from 'echarts'
import elementResizeDetectorMaker from 'element-resize-detector'
export default {
  name: 'BaseChart',
  props: {
    // 图表的宽度
    width: {
      type: String,
      default: '600px'
    },
    // 图表的高度
    height: {
      type: String,
      default: '400px'
    },
    // 图表的配置
    option: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      chart: null
    }
  },
  computed: {
    style() {
      return {
        width: this.width,
        height: this.height
      }
    }
  },
  watch: {
    option: {
      deep: true,
      handler() {
        this.initChart()
      }
    }
  },
  mounted() {
    this.initChart()
    this.handleResize()
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    // 销毁图表实例
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    // 初始化图表
    initChart() {
      // 如果没有图表实例,则创建一个新的实例
      if (!this.chart) {
        this.chart = echarts.init(this.$refs.chart)
      }
      this.chart.setOption(this.option)
    },
    // 处理图表容器大小变化
    handleResize() {
      const erd = elementResizeDetectorMaker()
      // 监听图表容器的大小变化
      erd.listenTo(this.$refs.chart, () => {
        // 改变图表尺寸
        this.chart.resize()
      })
    }
  }
}
</script>

<style lang="scss" scoped></style>

使用

使用计算属性来返回图表配置,数据变化了会重新生成配置,然后图表就会自动更新

xml 复制代码
<template>
  <div>
    <!-- 折线图 -->
    <BaseChart width="100%" height="300px" :option="lineOption" />
    <div style="display: flex;height: 300px;">
      <!-- 柱状图 -->
      <BaseChart width="50%" height="100%" :option="barOption" />
      <!-- 饼图 -->
      <BaseChart width="50%" height="100%" :option="pieOption" />
    </div>
  </div>
</template>
<script>
import BaseChart from '@/components/BaseChart'
export default {
  components: {
    BaseChart
  },
  data() {
    return {
      type: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
      data: [820, 932, 901, 934, 1290, 1330, 1320]
    }
  },
  computed: {
    // 折线图配置
    lineOption() {
      const option = {
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            type: 'line',
            data: this.data,
            smooth: true
          }
        ]
      }
      return option
    },
    // 柱状图配置
    barOption() {
      const option = {
        xAxis: {
          type: 'category',
          data: this.type
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            type: 'bar',
            data: this.data
          }
        ]
      }
      return option
    },
    // 饼图配置
    pieOption() {
      const option = {
        tooltip: {
          trigger: 'item'
        },
        legend: {
          top: '5%',
          left: 'center'
        },
        series: [
          {
            type: 'pie',
            radius: ['40%', '70%'],
            avoidLabelOverlap: false,
            label: {
              show: false,
              position: 'center'
            },
            emphasis: {
              label: {
                show: true,
                fontSize: 40,
                fontWeight: 'bold'
              }
            },
            labelLine: {
              show: false
            },
            data: this.type.map((item, index) => ({
              value: this.data[index],
              name: item
            }))
          }
        ]
      }
      return option
    }
  },
  mounted() {
    this.genData()
    // 开启一个定时器,数据变化后,图表也会更新
    setInterval(() => {
      this.data = this.genData()
    }, 3000)
  },
  methods: {
    // 生成数据
    genData() {
      return this.type.map(item => Math.ceil(Math.random() * 1000))
    }
  }
}
</script>

效果

调整窗口大小变化,图表也会自适应

结语

封装好这个基础组件后,我们在项目其他地方用到图表,直接引入这个组件就可以了,使用计算属性来返回配置,我们只关注数据即可,数据变化,图表自动变化。

相关推荐
只愿云淡风清7 小时前
ECharts地图数据压缩-ZigZag算法
前端·javascript·echarts
_菜鸟果果4 天前
Vue3+echarts 3d饼图
前端·javascript·echarts
java水泥工4 天前
基于Echarts+HTML5可视化数据大屏展示-电信厅店营业效能分析
前端·echarts·html5·大屏展示
paopaokaka_luck4 天前
基于SpringBoot+Vue的数码交流管理系统(AI问答、协同过滤算法、websocket实时聊天、Echarts图形化分析)
vue.js·人工智能·spring boot·websocket·echarts
麦麦大数据5 天前
F024 RNN+Vue+Flask电影推荐可视化系统 python flask mysql 深度学习 echarts
python·rnn·深度学习·vue·echarts·电影推荐
xiaohe06016 天前
🎉 Uni ECharts 2.0 正式发布:原来在 uni-app 中使用 ECharts 可以如此简单!
uni-app·echarts
码界筑梦坊8 天前
267-基于Django的携程酒店数据分析推荐系统
python·数据分析·django·毕业设计·echarts
HashTang8 天前
2025年10月实时最新获取地图边界数据方法,省市区县街道多级联动【文末附实时geoJson数据下载】
信息可视化·echarts·geojson·乡镇geojson·街道边界·geomap·街道geo
啦工作呢9 天前
数据可视化 ECharts
前端·信息可视化·echarts
U.2 SSD11 天前
Echart仪表盘示例
javascript·echarts