防抖和节流就是针对响应跟不上触发频率这类问题的两种解决方案。在给 DOM 绑定事件时,有些事件我们是无法控制触发频率的。 如鼠标移动事件 onmousemove, 滚动滚动条事件 onscroll,窗口大小改变事件 onresize,瞬间的操作都会导致这些事件会被高频触发。 如果事件的回调函数较为复杂,就会导致响应跟不上触发,出现页面卡顿,假死现象。 在实时检查输入时,如果我们绑定 onkeyup 事件发请求去服务端检查,用户输入过程中,事件的触发频率也会很高,会导致大量的请求发出,响应速度会大大跟不上触发。
created
生命周期将this.debounce
绑定到this
上,这样this.debounce
就可以在created
生命周期中使用。watch
函数中,使用this.debounce
调用debounce
函数,并传入this.debounce
的回调函数。this.debounce
调用clear
函数,清除定时器。<template>
<input v-model="value" type="text" />
<p>{{ value }}</p>
</template>
<script>
import debounce from 'lodash.debounce'
export default {
data() {
return {
value: ''
}
},
watch: {
value(...args) {
this.debouncedWatch(...args)
}
},
created() {
this.debouncedWatch = debounce((newValue, oldValue) => {
console.log('New value:', newValue)
}, 500)
},
beforeUnmount() {
this.debouncedWatch.cancel()
}
}
</script>
<template>
<input v-on:input="debouncedHandler" type="text" />
</template>
<script>
import debounce from 'lodash.debounce'
export default {
created() {
this.debouncedHandler = debounce((event) => {
console.log('New value:', event.target.value)
}, 500)
},
beforeUnmount() {
this.debouncedHandler.cancel()
}
}
</script>
为什么不适用debounce
或throttle
直接绑定函数呢?比如:
<template>
<input v-on:input="debouncedHandler" type="text" />
</template>
<script>
import debounce from 'lodash.debounce'
export default {
methods: {
// Don't do this!
debouncedHandler: debounce(function (event) {
console.log('New value:', event.target.value)
}, 500)
}
}
</script>
使用export default { ... }
从组件导出的 options 对象,包括方法,将被组件的所有实例重用。如果网页中有 2 个或更多的组件实例,那么所有的组件都将使用相同的debounce
或throttle
的函数方法。
在 vue
中使用 debounce
和 throttle
函数,应该在 created
和 beforeUnmount
生命周期中使用,而不是在 watch
中使用。
<template>
<input v-on:input="debouncedHandler" type="text" />
</template>
<script>
export default {
created() {
this.debouncedCallback = debounce((...args) => {
// The debounced
callback
}, 500)
},
watch: {
value(...args) {
this.debouncedCallback(...args)
}
}
}
</script>