Wie verwende ich Anti-Shake und Throttling in Vue-Komponenten? Der folgende Artikel zeigt Ihnen anhand von Beispielen, wie Sie Anti-Shake- und Throttling-Kontrollbeobachter und Event-Handler in Vue-Komponenten verwenden.
Seien Sie vorsichtig, wenn Sie häufig ausgelöste Ereignisse überwachen, z. B. Benutzereingaben in das Eingabefeld, Fenstergrößenänderung, Scrollen und Intersection Observer-Ereignisse.
Diese Ereignisse werden immer häufig ausgelöst, vielleicht alle paar Sekunden. Es wäre unklug, für jedes Ereignis eine Abrufanforderung (oder ein ähnliches Verhalten) auszugeben.
Alles, was wir tun müssen, ist die Ausführung des Event-Handlers zu verlangsamen. Bei dieser Pufferungstechnologie handelt es sich um „Entprellen und Drosseln“. In diesem Artikel erfahren Sie, wie Sie mit Anti-Shake und Throttling Watcher und Event-Handler in Vue-Komponenten steuern. [Verwandte Empfehlungen: „
vue.js Tutorial<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>
https://codesandbox.io/s/vue-input-szgn1?file=/src/App.vue
Öffnen Sie die Demo und geben Sie ein paar Zeichen in das Eingabefeld ein. Bei jeder Eingabe wird der Wert in der Konsole protokolliert.
Wir haben den Protokolldruck implementiert, indem wir einen Watcher verwendet haben, um das Datenattribut value
abzuhören. Wenn Sie jedoch eine GET-Anfrage mit value
als Parameter in den Rückruf des Beobachters einschließen möchten, sollten Sie nicht damit rechnen, die Anfrage zu häufig zu stellen.
Machen wir etwas Anti-Shaking für das Verhalten beim Drucken von Konsolenprotokollen. Die Kernidee besteht darin, eine Entprellfunktion zu erstellen und diese Funktion dann im Beobachter aufzurufen. value
数据属性 来实现了打印日志。但如果你想在 观察者的回调 中加入一个 使用 value
作为参数 的 GET 请求,那你应该不会期望太过频繁地发起请求。
我们来对 打印控制台日志 这个行为做一下 防抖。核心思想是创建一个 防抖函数,然后在 观察者 内部调用该函数。
我在这里选择了 'lodash.debounce'
的 防抖实现,但你可以自由选择喜欢的实现方式。
我们来将 防抖逻辑 应用到组件:
<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>
试试 demo
https://codesandbox.io/s/vue-input-debounced-4vwex?file=/src/App.vue
如果你打开这个 demo,你会发现其实从用户角度来看,变化不大:你依旧可以像上一个 demo 中一样自由输入字符。
但有一个区别:只有在最后一次输入的 500ms
之后,才会将新的输入值打印日志到控制台。这说明 防抖 在生效。
观察者 的 防抖实现 只需要 3 个简单步骤:
在 create()
钩子 里,创建 防抖回调,并将其赋值到实例上:this.debouncedWatch = debounce(..., 500)
。
在 观察者 回调 watch.value() { ... }
中 传入正确的参数 调用 this.debouncedWatch()
。
最后,beforeUnmount()
钩子中 调用 this.debouncedWatch.cancel()
,在卸载组件之前,取消所有还在 pending 的 防抖函数执行。
采用同样的方式,你可以对任意数据属性的 观察者 应用 防抖。然后就可以安全执行 防抖回调内部的一些比较重的操作,比如 网络请求、繁重的 DOM 操作,等等。
上面一节,我展示了如何对 观察者 使用 防抖,那么常规的事件处理器呢?
我们重用之前用户输入数据到输入框的例子,但这一次会给输入框加个 事件处理器。
像往常一样,如果你没有采取任何缓冲的措施,每当值被修改时,会被打印到控制台:
<template> <input v-on:input="handler" type="text" /> </template> <script> export default { methods: { handler(event) { console.log('New value:', event.target.value); } } }; </script>
试试 demo:
https://codesandbox.io/s/vue-event-handler-plls4?file=/src/App.vue
打开这个 demo,在输入框打几个字符。看看控制台:你会发现每次你输入的时候就会有日志被打印出来。
同样,如果你会执行一些比较重的操作(比如网络请求),可就不合适了。
对 事件处理器 使用 防抖,可以参考下面这个:
<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>
试试 demo:
https://codesandbox.io/s/vue-event-handler-debounced-973vn?file=/src/App.vue
打开 demo,输入一些字符。组件只有在最后一次输入的 500ms
之后,才会将新的输入值打印日志到控制台。防抖 再一次生效了!
事件处理器 的 防抖实现 只需要 3 个步骤:
.在 create()
钩子 里,创建实例后,立刻将 防抖回调 debounce(event => {...}, 500)
赋值到 this.debouncedHandler
'lodash.debounce'
gewählt, aber Sie können die Implementierung frei wählen, die Ihnen gefällt. 🎜🎜Lassen Sie uns die Entprelllogik auf die Komponente anwenden: 🎜// ... methods: { // Why not? debouncedHandler: debounce(function () { ... }}, 500) } // ...
500ms
nach der letzten Eingabe in der Konsole protokolliert. Dies zeigt, dass Anti-Shake greift. 🎜🎜Die Anti-Shake-Implementierung des Beobachters erfordert nur drei einfache Schritte: 🎜create()
Anti -bounce-Rückruf und weisen Sie ihn der Instanz zu: this.debouncedWatch = debounce(..., 500)
. 🎜watch.value() { ...
die richtigen Parameter und rufen Sie this.debouncedWatch()
auf. 🎜this.debouncedWatch.cancel()
im beforeUnmount()
-Hook auf, um alle ausstehenden Komponenten abzubrechen, bevor Sie die Komponente deinstallieren Anti-Shake-Funktion wird ausgeführt. 🎜<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>
// ... created() { this.debouncedCallback = debounce((...args) => { // The debounced callback }, 500); }, // ...
500 ms
nach der letzten Eingabe in der Konsole. Anti-Shake funktioniert wieder! 🎜🎜Die Anti-Shake-Implementierung des Event-Handlers erfordert nur 3 Schritte: 🎜create()
-Hook Weisen Sie nach dem Erstellen der Instanz sofort den Debounce-Rückruf debounce(event => {...}, 500)
this.debouncedHandler
zu. 🎜在输入框的 template 中 给 v-on:input
赋上 debouncedHandler
:<input v-on:input="debouncedHandler" type="text" />
最后,在卸载组件之前, 在 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 中的 防抖 和 节流 还什么问题吗?欢迎提问!
更多编程相关知识,请访问:编程入门!!
Das obige ist der detaillierte Inhalt vonEine kurze Analyse der Verwendung von Anti-Shake und Throttling in Vue-Komponenten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!