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

效果

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

结语

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

相关推荐
匹马夕阳19 小时前
ECharts极简入门
前端·信息可视化·echarts
禾苗种树21 小时前
在 Vue 3 中使用 ECharts 制作多 Y 轴折线图时,若希望 **Y 轴颜色自动匹配折线颜色**且无需手动干预,可以通过以下步骤实现:
前端·vue.js·echarts
不想上班只想要钱10 天前
ECharts鼠标悬浮提示框数字设置鼠标在左侧时 tooltip 显示到右侧,鼠标在右侧时 tooltip 显示到左侧。
javascript·计算机外设·echarts
枫叶落雨22212 天前
11苍穹外卖之Apache ECharts(数据可视化图表、后端传数据)
信息可视化·apache·echarts
祁许12 天前
【Vue】在Vue3中使用Echarts的示例 两种方法
前端·vue.js·typescript·vue·echarts
ctf_022613 天前
echarts 3d中国地图飞行线
3d·echarts·swift
Kill_paradise14 天前
echarts 鼠标移入柱状图展示手指,移入label 展示箭头
前端·javascript·echarts
cccc☜15 天前
echarts加载地图
前端·javascript·echarts
大厂在职_few16 天前
Android版&Kotlin版RxJava2+Retrofit2+OkHttp3的基础、封装和项目中的使用
android·kotlin·echarts
kidding72317 天前
Vue3使用Echarts组件步骤
前端·vue.js·echarts