第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>
✅ 测试步骤
- 保存
echartHelper.js和页面 vue 文件,刷新页面 - 柱状图正常渲染
- 点击柱子,弹出弹窗,展示当前柱子的名称和数值;控制台打印 params 对象
- 窗口缩放,防抖 resize 正常生效
- 切换路由离开页面,事件自动随实例销毁,不会残留事件监听
