ECharts 封装与使用实战(基于 Vue3

ECharts 是一个用于可视化数据的图表库,支持多种图表类型,比如折线图、柱状图、饼图等。其文档详尽,使用简单,在数据可视化领域广泛应用。

本文将从结构理解、封装、数据对接与最终使用四个方面,介绍如何在 Vue3 项目中优雅地使用 ECharts。

一、ECharts 的基本结构

ECharts 的使用分为三个核心步骤:

  • 准备 DOM:创建图表要挂载的 DOM 节点;

  • 初始化实例:基于该 DOM 创建 ECharts 实例;

  • 设置数据 :调用 setOption 方法绘制数据图表。

实际上,我们的封装思路也正是基于以上流程进行的。

二、封装 useChart 组合函数

typescript 复制代码
// useChart.ts
import { markRaw, onBeforeUnmount, onMounted, type Ref } from 'vue'
import { ref } from 'vue'
import * as echarts from 'echarts'

export function useChart(chartRef: Ref<HTMLElement | null>, setChartData: () => Promise<any>) {
  const chartInstance = ref<echarts.ECharts | null>(null)

  const initChart = async () => {
    if (chartRef.value) {
      // 初始化图表,并使用 markRaw 取消响应式,避免 resize 异常
      chartInstance.value = markRaw(echarts.init(chartRef.value))
      const options = await setChartData()
      chartInstance.value.setOption(options)
    }
  }

  // 自动响应窗口变化
  const resizeChart = () => {
    chartInstance.value?.resize()
  }

  onMounted(() => {
    initChart()
    window.addEventListener('resize', resizeChart)
  })

  onBeforeUnmount(() => {
    window.removeEventListener('resize', resizeChart)
    chartInstance.value?.dispose()
  })
}

说明

  • chartRef:绑定图表 DOM 的 ref

  • setChartData:用于返回图表配置项的函数,通常会包含接口数据处理。

三、图表数据的准备

1. 定义基础模板

php 复制代码
const setChartData = async () => {
  const chartOptions = reactive({
    title: { text: '用电统计' },
    tooltip: { trigger: 'axis' },
    legend: { data: [] },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: ['13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00','20:00','21:00']
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 200,
      interval: 20,
      axisLabel: { formatter: '{value} KW' }
    },
    series: [
      { name: '', type: 'line', smooth: true, data: [], markPoint: { data: [{ type: 'max', name: 'Max' }, { type: 'min', name: 'Min' }] } },
      { name: '', type: 'line', smooth: true, data: [], markPoint: { data: [{ type: 'max', name: 'Max' }, { type: 'min', name: 'Min' }] } },
      { name: '', type: 'line', smooth: true, data: [], markPoint: { data: [{ type: 'max', name: 'Max' }, { type: 'min', name: 'Min' }] } }
    ]
  })

  // 模拟请求接口
  const res = await chartDataApi()

  chartOptions.legend.data = res.data.list.map((item: any) => item.name)
  for (let i = 0; i < res.data.list.length; i++) {
    chartOptions.series[i].name = res.data.list[i].name
    chartOptions.series[i].data = res.data.list[i].data
  }

  return chartOptions
}

2. 模拟接口数据结构

css 复制代码
// 接口返回结构
{
  code: 200,
  message: "操作成功",
  data: {
    list: [
      { name: "设备A", data: [201, 501, 301, 70, 601, 80, 401, 60, 50] },
      { name: "设备B", data: [401, 601, 501, 80, 701, 90, 601, 70, 80] },
      { name: "设备C", data: [301, 401, 601, 50, 701, 20, 301, 40, 60] }
    ]
  }
}

四、在组件中使用图表

1. 模板中挂载 DOM

xml 复制代码
<template>
  <div ref="chart1" class="chart"></div>
</template>


<script setup lang="ts">
import { ref } from 'vue'
import { useChart } from '@/composables/useChart'
import { setChartData } from '@/api/chart'

const chart1 = ref<HTMLElement | null>(null)
useChart(chart1, setChartData)
</script>

问:为什么组件中不需要再写 onMounted? 答:这是 组合函数共享组件上下文 的特性。在 useChart 内部调用了 onMounted(),Vue 会自动将它注册到当前使用该组合函数的组件生命周期中。如果在组件的 onMounted()调用 useChart。那 useChart中可以不写onMounted()

欢迎大家留言探讨你们的实践经验,如有疏漏或不妥之处,欢迎在评论区指出,互相学习,共同进步!

相关推荐
Jimmmmmmm20 分钟前
pnpm如何避免幻影依赖:从node_modules演进史说起
前端
拾光拾趣录21 分钟前
如何优雅地实现每 5 秒轮询请求?
前端·javascript
snowbitx30 分钟前
Vue开发尝试一下
前端
前端缘梦33 分钟前
JavaScript 高频面试题精讲:var、let、const 与类型系统全解析
前端·面试
阿慧勇闯大前端34 分钟前
TypeScript 从入门到放弃any:老大说再写 any 就扣钱!
前端
AI悦创Python辅导35 分钟前
路径分析到底怎么玩?一文搞懂!
前端
mrsk35 分钟前
用魔塔来体验一把NLP(机械学习)
前端·机器学习·面试
袋鱼不重36 分钟前
Vue3 Effect源码解析
前端·javascript·vue.js
福娃B36 分钟前
【React】React 状态管理与组件通信:Zustand vs Redux📦
前端·react.js·前端框架
硅基宙宇AIGC38 分钟前
亲测鹅厂Codebuddy!抢到多个邀请码后发现了AI编程的天花板?(文末送码)
前端·后端