第15章:ECharts 图表事件交互(若依 Vue3)

第15章:ECharts 图表事件交互(若依 Vue3)

业务场景:点击柱状图柱子 / 饼图扇区,拿到当前点击的数据,弹出弹窗、跳转页面,后台管理看板高频使用。基于上一节封装好的 useEcharts 组合式函数,新增事件绑定。

1、修改 @/composables/echartHelper.js,新增事件绑定能力

复制代码
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import * as echarts from 'echarts'

// 防抖工具函数
function debounce(fn, delay = 300) {
  let timer = null
  return function (...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

export function useEcharts() {
  const chartRef = ref(null)
  let chartInstance = null
  let instanceReadyResolve = null
  const instanceReady = new Promise(resolve => {
    instanceReadyResolve = resolve
  })

  // 初始化图表
  const initChart = async () => {
    await nextTick()
    if (!chartRef.value) return
    chartInstance = echarts.init(chartRef.value)
    instanceReadyResolve()
  }

  const setChartOption = async (option) => {
    await instanceReady
    if (!chartInstance) return
    chartInstance.setOption(option, { notMerge: true })
  }

  const resizeChart = () => {
    chartInstance && chartInstance.resize()
  }
  const debounceResize = debounce(resizeChart, 300)

  // ✅ 新增:绑定echarts事件
  const onChartEvent = async (eventName, callback) => {
    await instanceReady
    chartInstance.on(eventName, callback)
  }

  // ✅ 新增:解绑echarts事件,防止内存泄露
  const offChartEvent = (eventName, callback) => {
    if(chartInstance){
      chartInstance.off(eventName, callback)
    }
  }

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

  onUnmounted(() => {
    window.removeEventListener('resize', debounceResize)
    if (chartInstance) {
      chartInstance.dispose()
      chartInstance = null
    }
  })

  return {
    chartRef,
    setChartOption,
    resizeChart,
    onChartEvent,
    offChartEvent
  }
}

2、页面组件完整代码(带点击事件,使用 Element Plus 弹窗)

复制代码
<template>
  <div class="chart-container">
    <el-alert title="点击柱状图柱子,弹出详情弹窗" type="info" style="margin-bottom:10px"/>
    <div
      ref="chartRef"
      style="width:100%;height:400px;border:1px solid #eee"
    ></div>

    <!-- 详情弹窗 -->
    <el-dialog v-model="dialogVisible" title="点击图表详情">
      <p>类别:{{ clickData.name }}</p>
      <p>数值:{{ clickData.value }}</p>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useEcharts } from '@/composables/echartHelper'
const { chartRef, setChartOption, onChartEvent } = useEcharts()

const dialogVisible = ref(false)
const clickData = ref({ name:'', value:0 })

const option = {
  title: { text: '图表点击事件测试' },
  xAxis: { type: 'category', data: ['周一','周二','周三','周四','周五'] },
  yAxis: { type: 'value' },
  series: [{ type: 'bar', data: [120, 200, 150, 80, 70] }]
}

// 渲染图表
setChartOption(option)

// 绑定点击事件
onChartEvent('click', (params)=>{
  console.log('点击参数', params)
  clickData.value = {
    name: params.name,
    value: params.value
  }
  dialogVisible.value = true
})
</script>

✅ 测试步骤

  1. 保存 echartHelper.js 和页面 vue 文件,刷新页面
  2. 柱状图正常渲染
  3. 点击柱子,弹出弹窗,展示当前柱子的名称和数值;控制台打印 params 对象
  4. 窗口缩放,防抖 resize 正常生效
  5. 切换路由离开页面,事件自动随实例销毁,不会残留事件监听
相关推荐
honkun61 小时前
vue甘特图组件 vxe-gantt 实现拖拽任务自动更新紧前紧后依赖线关联任务的日期
vue.js·vxe-gantt
雪芽蓝域zzs2 小时前
第20章:ECharts 图表主题切换 + 自定义颜色渐变
vue.js·echars
mldong2 小时前
给流程设计器加国际化,我没引 vue-i18n
前端·javascript·vue.js
边境悍匪3 小时前
蜗牛学苑 Java 智能体学习 Day46|贯穿项目 2 思维导图复盘
java·开发语言·vue.js·学习·spring
+VX:Fegn089516 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
雪芽蓝域zzs16 小时前
第 7 章:双 Y 轴组合图(柱状 + 折线,看板高频场景)
vue.js·echars
一 乐16 小时前
二手交易平台|基于springboot + vue二手交易平台(源码+数据库+文档)
java·数据库·vue.js·spring boot·小程序
vx-程序开发17 小时前
【计算机毕设】django校园跑腿服务系统83141
java·数据库·vue.js·spring boot·spring·elasticsearch·django
雪芽蓝域zzs17 小时前
第 2 章:封装 ECharts 通用 Composable(echartHelper.js)
echars