防抖实战
防抖的概念
-
防抖是一种控制函数执行频率的技术,它确保一个函数在短时间内被多次触发时,只执行一次。
-
比喻理解
- 想象电梯关门的过程:
- 有人进电梯(触发事件)
- 电梯等待5秒(防抖时间)
- 如果5秒内又有人进来(再次触发),重新等待5秒
- 直到5秒内没人进来,电梯才真正关门(执行函数)
描述:在某些图像点击的情况下,比如说 柱状图 或者 饼图,点击事件会造成一下子多次执行操作,此时就可以使用防抖来操作
<template>
<simple-chart
ref="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 // 等待结束后执行
});
···