防抖的实战例子 - 常用语echarts图中点击事件的例子
防抖实战
防抖的概念
-
防抖是一种控制函数执行频率的技术,它确保一个函数在短时间内被多次触发时,只执行一次。
-
比喻理解
- 想象电梯关门的过程:
- 有人进电梯(触发事件)
- 电梯等待5秒(防抖时间)
- 如果5秒内又有人进来(再次触发),重新等待5秒
- 直到5秒内没人进来,电梯才真正关门(执行函数)
描述:在某些图像点击的情况下,比如说 柱状图 或者 饼图,点击事件会造成一下子多次执行操作,此时就可以使用防抖来操作
<template><simple-chartref="chartRef":title="{show: false,}":resize-delay="0":colors="lineColor":legend="{show: false}":height="chartHeight":dataset-source="chartData || []":textStyle="{color: 'red'}":seriesConfig="seriesConfig()":x-axis="{ ...xAxisConfig }":y-axis="[{ ...yAxisConfig }]":grid="{top: '5%',bottom: '15%',left: '4%',right: '5%'}":bgColor="backgroundColor":data-zoom="[{ type: 'slider', show: false }]":loading-config="{ maskColor: '#FFFFFF11', textColor: '#CCC' }":custom-tooltip="{trigger: 'axis',axisPointer: { type: 'none' },formatter: tooltipFormatter,borderColor: '#2861C2'}":safeUpdate="isUpdate":markLineShow="true"@click-data="debouncedHandleBarClick" ></simple-chart>
</template><script setup>
import SimpleChart from '@/components/echart/SimpleChart.vue';
import { useRouter } from 'vue-router';
import { debounce } from 'lodash-es';const router = useRouter();
const props = defineProps({ chartHeight: {type: [String, Number],default: '26vh'},xData: {type: Array,default: () => ['FOL', 'FVN', 'FJZ', 'FSJ', 'FTX', 'FCZ']},chartData: {type: Array,default: () => [{ name: 'FOL', value: 1509 },{ name: 'FVN', value: 1467 },{ name: 'FJZ', value: 993 },{ name: 'FSJ', value: 478 },{ name: 'FTX', value: 984 },{ name: 'FCZ', value: 1005 }]},chartTitle: {type: String,default: 'resource'},isUpdate: {type: Boolean,default: false}, accessBackend: {type: Boolean,default: false}
});const yAxisMax = computed(() => {if (!props.chartData || props.chartData.length === 0) return 2500; const maxValue = Math.max(...props.chartData.map((item) => item.value));return maxValue + 100;
});let xAxisConfig = ref({type: 'category',axisLine: { lineStyle: { color: 'rgb(185, 232, 255)' }},axisLabel: {fontSize: 10,color: '#B9E8FF',interval: 0,formatter: (value) => {return `{label|${value}}`;},rich: {label: {padding: [0, 0, 0, 10],color: '#B9E8FF',fontSize: 10}}},axisTick: {show: false},data: props.xData
});
const yAxisConfig = ref({show: true,type: 'value',name: '',min: 0,max: yAxisMax.value,axisLabel: {color: '#B9E8FF',fontSize: 10,formatter: '{value}'},axisTick: {show: false},axisLine: {show: true,symbolOffset: [0, 0],symbol: ['none', 'none'],lineStyle: {color: 'rgb(209, 212, 215)'}},splitLine: {show: true,lineStyle: {width: 1,type: 'dashed', color: 'rgb(235, 237, 238, 0.4)'}}
});const seriesConfig = () => {const backgroundData = props.chartData.map(() => 2500);const barData = props.chartData.map((item) => item.value);return [{// 背景矩阵data: backgroundData, type: 'bar',barWidth: '70%',itemStyle: {color: 'rgba(108, 130, 151, 0.1)',barBorderRadius: [5, 5, 0, 0]},silent: true,tooltip: { show: false }, z: 1},{// 主柱状矩阵data: barData, type: 'bar',barWidth: '30%',barGap: '-73%',itemStyle: {color: 'rgb(7, 106, 235)',barBorderRadius: [3, 3, 0, 0]},label: {show: true,position: 'top',color: 'rgba(255, 255, 255, 1)',fontSize: 12,fontWeight: 700,formatter: (params) => {return params.value;}},z: 2}];
};watch(() => props.chartData, () => {yAxisConfig.value.max = yAxisMax.value;
}, { deep: true });const handleBarClick = (params) => {if(!props.accessBackend) {// ElMessage.closeAll();return ElMessage({type: 'error',message: "Sorry, you don't have permission, please contact genius team",showClose: true,duration: 0});}if (params.seriesIndex === 1) {router.push({path: '/monitoring',query: { site: params.name }});}
};// 创建防抖函数实例
const debouncedHandleBarClick = debounce(handleBarClick, 300, {leading: false, // 不立即执行trailing: true // 等待结束后执行
});const tooltipFormatter = (params) => {const item = params[0];return `${item.marker} ${item.name}: ${item.value}`;
};onBeforeUnmount(() => {debouncedHandleBarClick.cancel(); // 在摧毁之前需要将防抖取消
});
</script>
防抖代码在debounce中已经封装好了,直接使用即可;
- 创建好的防抖函数实例
···
const debouncedHandleBarClick = debounce(handleBarClick, 300, {
leading: false, // 不立即执行;事件触发的时候不立即执行函数
trailing: true // 等待结束后执行
});
···