搜索框每敲一个字母就发请求,既浪费流量也容易打爆接口。Vue3 里把防抖封装成自定义指令,页面只要在输入框上挂 v-debounce 即可,逻辑集中在指令里,代码复用度极高。
实现思路
指令 mounted 时给元素绑定 input 事件,回调内先 clearTimeout 再重新 setTimeout,只有停止输入超过指定毫秒才调用业务方法;指令卸载时 Vue 会自动解绑监听,无需手动清理。
指令定义
// src/directives/debounce.js
const debounce = {
mounted(el, binding) {
let timer = null;
// v-debounce:500 中的 500 即延迟毫秒
const delay = binding.arg ? Number(binding.arg) : 300;
const handler = binding.value;
el.addEventListener("input", () => {
clearTimeout(timer);
timer = setTimeout(() => {
handler.call(el, el.value);
}, delay);
});
}
};
export default {
install(app) {
app.directive("debounce", debounce);
}
};
页面使用
<template>
<!-- 停止输入 500ms 后触发 onSearch,参数为最新输入值 -->
<input v-model="keyword" v-debounce:500="onSearch" />
</template>
<script setup>
import { ref } from "vue";
const keyword = ref("");
const onSearch = (val) => {
console.log("触发搜索:", val);
// 在此调用列表接口
};
</script>扩展玩法
- main.js 里 app.use(debouncePlugin) 注册后全项目可用;
- 需要点击防抖时把监听事件名换为 click 即可;
- 防抖不适用场景可用节流思路:固定周期内只触发一次。
小结
指令把 DOM 事件处理与业务解耦,一个 v-debounce 取代全项目到处 new 的 setTimeout,是 Vue3 工程化的常规优化点。
评论(0)
暂无评论,快来抢沙发吧~