Vue2 和 Vue3 里的防抖:简单说清楚怎么用
啥是防抖?
说白了,防抖就是让一个函数 “冷静” 一会儿再执行。比如用户疯狂点按钮、输入框快速打字,咱们不想每次都触发函数,而是等他停下手来再执行,这就是防抖的作用。
标题为啥要用防抖?
减少请求次数,减轻服务器压力(比如搜索框实时联想)
避免频繁操作 DOM,提升页面性能
防止用户误操作(比如重复提交表单)
Vue2 里怎么写防抖?
方法 1:用 lodash(推荐)
先装包:
npm install lodash --save
然后在组件里用:
import { debounce } from 'lodash'export default {data() {return {searchText: ''}},methods: {// 定义防抖处理函数,延迟500ms执行handleSearch: debounce(function() {// 这里写你的搜索逻辑console.log('搜索:', this.searchText)}, 500)},beforeDestroy() {// 组件销毁前取消防抖,避免内存泄漏this.handleSearch.cancel()}
}
模板里直接用:
<input v-model="searchText" @input="handleSearch" placeholder="输入搜索内容">
方法 2:自己实现简易版
不想引库的话,自己写一个也很简单:
export default {data() {return {searchText: '',timer: null // 用来存定时器}},methods: {handleSearch() {// 每次触发先清掉之前的定时器clearTimeout(this.timer)// 500ms后再执行this.timer = setTimeout(() => {console.log('搜索:', this.searchText)}, 500)}},beforeDestroy() {// 清理定时器clearTimeout(this.timer)}
}
Vue3 里怎么写防抖?
方法 1:Options API(跟 Vue2 差不多)
import { debounce } from 'lodash'
import { defineComponent } from 'vue'export default defineComponent({data() {return {searchText: ''}},methods: {handleSearch: debounce(function() {console.log('搜索:', this.searchText)}, 500)},beforeUnmount() {this.handleSearch.cancel()}
})
方法 2:Composition API(推荐)
import { debounce } from 'lodash'
import { ref, onUnmounted } from 'vue'export default {setup() {const searchText = ref('')// 定义防抖函数const handleSearch = debounce(() => {console.log('搜索:', searchText.value)}, 500)// 组件卸载时清理onUnmounted(() => {handleSearch.cancel()})return {searchText,handleSearch}}
}
方法 3:自己实现(Composition API 版)
import { ref, onUnmounted } from 'vue'export default {setup() {const searchText = ref('')let timer = nullconst handleSearch = () => {clearTimeout(timer)timer = setTimeout(() => {console.log('搜索:', searchText.value)}, 500)}// 组件卸载时清理onUnmounted(() => {clearTimeout(timer)})return {searchText,handleSearch}}
}
注意事项
1、防抖时间设置:一般 300-500ms 比较合适,根据实际需求调整
2、this 指向:用 lodash 的 debounce时,箭头函数会丢失 this,所以示例里用了普通函数
3、清理工作:组件销毁 / 卸载时一定要取消防抖或清除定时器,不然可能会有意外 bug
4、不要滥用:不是所有场景都需要防抖,比如点击按钮提交表单可以用,但实时显示输入长度就没必要