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

效果

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

结语

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

相关推荐
懒大王95273 天前
echarts+HTML 绘制3d地图,加载散点+散点点击事件
前端·html·echarts
实习生小黄3 天前
echarts 实现环形渐变
前端·echarts
南茗啊4 天前
echarts地图轮播markpoint-自用记录📝
前端·echarts
用户26124583401614 天前
饼图数据过多时,图例分成左右两列对称展示,可滚动翻页
前端·echarts
小谭鸡米花5 天前
ECharts各类炫酷图表/3D柱形图
前端·javascript·echarts·大屏端
DataGear7 天前
DataGear 企业版 1.4.0 发布,数据可视化分析平台
javascript·信息可视化·数据分析·html·echarts·数据可视化
DataGear7 天前
DataGear 5.3.0 制作支持导出表格数据的数据可视化看板
javascript·信息可视化·数据分析·html·echarts·数据可视化
抹茶san8 天前
echarts菜鸟踩坑——inverse 反向坐标轴
前端·echarts
DDDiccc8 天前
项目-苍穹外卖(十五) Apache ECharts+数据统计
前端·apache·echarts
霓虹伊9 天前
Echarts series line图形markLine的使用
echarts