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

效果

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

结语

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

相关推荐
Chan1610 小时前
【智能协同云图库】基于统一接口架构构建多维度分析功能、结合 ECharts 可视化与权限校验实现用户 / 管理员图库统计、通过 SQL 优化与流式处理提升数据
java·spring boot·后端·sql·spring·intellij-idea·echarts
zhangzuying102613 小时前
基于Vue3 +ElementuiPlus + Dexie.js自研的浏览器插件新建标签页tab
vue.js·typescript·echarts
java水泥工2 天前
基于Echarts+HTML5可视化数据大屏展示-学生综合成绩评价系统大屏
spring boot·echarts·html5
java水泥工3 天前
基于Echarts+HTML5可视化数据大屏展示-茶叶种植大数据溯源平台
大数据·echarts·html5
java水泥工3 天前
基于Echarts+HTML5可视化数据大屏展示-图书馆大屏看板
前端·echarts·html5
java水泥工4 天前
基于Echarts+HTML5可视化数据大屏展示-旅游智慧中心
数据分析·echarts·html5
不吃香菜的猪6 天前
uniapp中使用echarts并且支持pc端的拖动、拖拽和其他交互事件
uni-app·echarts·交互
Lsx-codeShare6 天前
前端数据可视化:基于Vue3封装 ECharts 的最佳实践
前端·javascript·echarts·vue3·数据可视化
java水泥工8 天前
基于Echarts+HTML5可视化数据大屏展示-惠民服务平台
前端·echarts·html5
Lsx_9 天前
前端数据可视化:基于Vue3封装 ECharts 的最佳实践
前端·vue.js·echarts