封装一个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>

效果

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

结语

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

相关推荐
paopaokaka_luck12 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
腾讯数据架构师1 天前
任务跑完怎么直接出图表?CubeStudio 任务可视化 ECharts 数据格式实操(CSV/JSON + metric.json,11 种图表一键渲染)
前端·json·echarts·数据可视化
总要学点什么2 天前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
paopaokaka_luck2 天前
社区服务平台(加权协同过滤推荐、Jieba中文词频分析、WebSocket实时聊天、求助处理闭环、 活动积分闭环、ECharts多维分析)
java·前端·spring boot·mysql·echarts·mybatis
mmsx3 天前
Android 并发考古:newThread 与 RxJava 共存,以及 GlobalScope 的三宗罪
android·echarts·rxjava
DataGear3 天前
DataGear 6.1.1 发布,数据可视化分析平台
javascript·信息可视化·数据分析·echarts·数据可视化
paopaokaka_luck4 天前
流浪动物救助与收养系统(DeepSeek AI对话、 ECharts多维分析、救助流程衔接、领养与回访衔接、 捐赠确认与公示、志愿者协作)
java·前端·javascript·人工智能·mysql·echarts·推荐算法
半生过往5 天前
智慧园区数字孪生大屏总结
echarts·three.js
Highcharts.js5 天前
2026年,AI正在重写技术:“工具思维”正在失效?
人工智能·echarts·客户端·highcharts·可视化图表·企业级图表
paopaokaka_luck6 天前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节