Home >Web Front-end >Vue.js >A brief analysis of how to use anti-shake and throttling in Vue components
How to use anti-shake and throttling in Vue components? The following article will show you how to use anti-shake and throttling control observers and event handlers in Vue components through examples. I hope it will be helpful to you!
Be careful when monitoring frequently triggered events, such as user typing in the input box, window resizing, scrolling, and Intersection Observer events.
These events are always triggered frequently, maybe once every few seconds. It would be unwise to issue a fetch request (or similar behavior) for every event.
All we need to do is slow down the execution of the event handler. This buffering technology is debounce and throttling.
In this article, you will learn how to use anti-shake and throttling control observers (watchers) and event handlers in Vue components. [Related recommendations: "vue.js Tutorial"]
We start with a simple component. Our task is to The text entered into the text box is output to the console:
<template> <input v-model="value" type="text" /> <p>{{ value }}</p> </template> <script> export default { data() { return { value: "", }; }, watch: { value(newValue, oldValue) { console.log("Value changed: ", newValue); } } }; </script>
Open demo:
https://codesandbox.io/s/vue-input-szgn1?file=/ src/App.vue
Open the demo and type a few characters in the input box. Each time it is entered, the value is logged to the console.
We implement the printing log by using a watcher to monitor the value
data attribute. But if you want to include a GET request with value
as a parameter in the observer's callback, then you should not expect to make the request too frequently.
Let’s do some anti-shaking for the behavior of printing console logs. The core idea is to create a debounce function and then call that function inside the observer.
I chose the anti-shake implementation of 'lodash.debounce'
here, but you are free to choose the implementation you like.
Let’s apply the debounce logic to the component:
<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>
Try the demo
https://codesandbox.io/s/vue-input-debounced -4vwex?file=/src/App.vue
If you open this demo, you will find that from a user perspective, not much has changed: you can still be as free as in the previous demo Enter characters.
But there is one difference: the new input value will be logged to the console only after 500ms
of the last input. This shows that anti-shake is taking effect.
The observer’s anti-shake implementation only requires 3 simple steps:
In the create()
hook, create an anti-shake callback and Assign it to the instance: this.debouncedWatch = debounce(..., 500)
.
Pass the correct parameters in the observer callback watch.value() { ... }
and call this.debouncedWatch()
.
Finally, beforeUnmount()
is called in the hook this.debouncedWatch.cancel()
, before uninstalling the component, cancel all pending The anti-shake function is executed.
In the same way, you can apply anti-shake to the observer of any data attribute. Then you can safely perform some heavier operations inside the anti-shake callback, such as network requests, heavy DOM operations, etc.
In the above section, I showed how to use anti-shake for observers, but what about regular event handlers?
We reuse the previous example of the user inputting data into the input box, but this time we will add an event handler to the input box.
As usual, if you do not take any buffering measures, whenever the value is modified, it will be printed to the console:
<template> <input v-on:input="handler" type="text" /> </template> <script> export default { methods: { handler(event) { console.log('New value:', event.target.value); } } }; </script>
Try the demo:
https://codesandbox.io/s/vue-event-handler-plls4?file=/src/App.vue
Open this demo and type a few characters in the input box. Take a look at the console: you'll notice that a log is printed every time you type.
Similarly, if you will perform some heavy operations (such as network requests), it is not suitable.
To use anti-shake on the event processor, you can refer to the following:
<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>
Try the demo:
https://codesandbox.io/s/vue -event-handler-debounced-973vn?file=/src/App.vue
Open the demo and enter some characters. The component will log the new input value to the console only 500ms
after the last input. Anti-shake works again!
The anti-shake implementation of the event processor only requires 3 steps:
. In the create()
hook, after creating the instance, immediately Assign the debounce callback debounce(event => {...}, 500)
to this.debouncedHandler
.
在输入框的 template 中 给 v-on:input
赋上 debouncedHandler
:72aa7f7a662c9ee5d7170c1b88786ba7
最后,在卸载组件之前, 在 beforeUnmount()
钩子中 调用 this.debouncedHandler.cancel()
,取消所有还在 pending 的 函数调用。
另一方面,这些例子应用了 防抖 的技术。然而,同样的方式可以以用于创建 节流函数。
你可能不理解:为什么不直接在 组件的 method
选项中创建 防抖函数,然后在 template 中调用这些方法作为事件处理器?
// ... methods: { // Why not? debouncedHandler: debounce(function () { ... }}, 500) } // ...
这比在实例对象上创建 防抖函数 要简单的多。
例如:
<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>
试试 demo
https://codesandbox.io/s/vue-event-handler-debounced-incorrectly-320ci?file=/src/App.vue
这次不是在 created()
钩子 里创建 防抖回调了,而是将 防抖回调 赋给了 methods.debouncedHandler
。
你如果试过 demo,你会发现是有效果的!
问题是,组件使用 export default { ... }
导出的 options 对象,包括方法,会被组件实例重用。
如果网页中有 2 个以上的组件实例,那么所有的组件都会应用 相同 的防抖函数 methods.debouncedHandler
— 这会导致防抖出现故障。
在 Vue 中,可以很轻松的对 观察者 和 事件处理器 应用 防抖 和 节流。
核心逻辑就是,在 created()
钩子 里,创建 防抖 或 节流 的回调,并赋值在实例上。
// ... created() { this.debouncedCallback = debounce((...args) => { // The debounced callback }, 500); }, // ...
A)然后在观察者内部调用实例上的防抖函数:
// ... watch: { value(...args) { this.debouncedCallback(...args); }, }, // ...
B)或在 template 中设定一个事件处理器:
<template> <input v-on:input="debouncedHandler" type="text" /> </template>
在这之后,每次调用 this.debouncedCallback(...args)
,就算执行频率非常高,内部的回调也能缓冲执行。
你对 Vue 中的 防抖 和 节流 还什么问题吗?欢迎提问!
更多编程相关知识,请访问:编程入门!!
The above is the detailed content of A brief analysis of how to use anti-shake and throttling in Vue components. For more information, please follow other related articles on the PHP Chinese website!