成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

溜到飛起,在 Vue 中使用防抖和節流

開發 前端
在本文中,你會了解到如何在 Vue 組件中 使用 防抖 和 節流 控制 觀察者(watchers) 和 事件處理程序。

在監聽頻繁觸發的事件時,一定要多加小心,比如 用戶在輸入框打字、窗口大小調整、滾動、Intersection Observer 事件。

這些事件總是被頻繁觸發,可能 幾秒一次。如果針對每次事件都發起 fetch 請求(或類似的行為),那顯然是不明智的。

我們需要做的就是減緩事件處理程序的執行速度。這種緩沖技術就是 防抖(debounce) 和 節流(throttle)[1] 。

在本文中,你會了解到如何在 Vue 組件中 使用 防抖 和 節流 控制 觀察者(watchers) 和 事件處理程序。

1. 觀察者 防抖

我們先從一個簡單的組件開始,我們的任務是 將用戶輸入到 文本框中的文本 輸出到控制臺:

<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>

打開demo[2]

打開 demo,在 輸入框 敲幾個字符。每次輸入時,值就會被 log 到控制臺。

我們通過使用 觀察者(watcher) 監聽 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[3]

如果你打開這個 demo,你會發現其實從用戶角度來看,變化不大:你依舊可以像上一個 demo 中一樣自由輸入字符。

但有一個區別:只有在最后一次輸入的 500ms 之后,才會將新的輸入值打印日志到控制臺。這說明 防抖 在生效。

觀察者 的 防抖實現 只需要 3 個簡單步驟:

  1. 在 create() 鉤子 里,創建 防抖回調,并將其賦值到實例上:this.debouncedWatch = debounce(..., 500)。
  2. 在 觀察者 回調 watch.value() { ... } 中 傳入正確的參數 調用 this.debouncedWatch()。
  3. 最后,beforeUnmount() 鉤子中 調用 this.debouncedWatch.cancel() ,在卸載組件之前,取消所有還在 pending 的 防抖函數執行。

采用同樣的方式,你可以對任意數據屬性的 觀察者 應用 防抖。然后就可以安全執行 防抖回調內部的一些比較重的操作,比如 網絡請求、繁重的 DOM 操作,等等。

2. 事件處理器 防抖

上面一節,我展示了如何對 觀察者 使用 防抖,那么常規的事件處理器呢?

我們重用之前用戶輸入數據到輸入框的例子,但這一次會給輸入框加個 事件處理器。

像往常一樣,如果你沒有采取任何緩沖的措施,每當值被修改時,會被打印到控制臺:

<template>
<input v-on:input="handler" type="text" />
</template>
<script>
export default {
methods: {
handler(event) {
console.log('New value:', event.target.value);
}
}
};
</script>

試試 demo[4]

打開這個 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[5]

打開 demo,輸入一些字符。組件只有在最后一次輸入的 500ms 之后,才會將新的輸入值打印日志到控制臺。防抖 再一次生效了!

事件處理器 的 防抖實現 只需要 3 個步驟:

  1. . 在 create() 鉤子 里,創建實例后,立刻將 防抖回調 debounce(event => {...}, 500) 賦值到 this.debouncedHandler 。
  2. 在輸入框的 template 中 給 v-on:input 賦上 debouncedHandler :<input v-on:input="debouncedHandler" type="text" />
  3. 最后,在卸載組件之前, 在 beforeUnmount() 鉤子中 調用 this.debouncedHandler.cancel() ,取消所有還在 pending 的 函數調用。

另一方面,這些例子應用了 防抖 的技術。然而,同樣的方式可以以用于創建 節流函數。

3. 注意

你可能不理解:為什么不直接在 組件的 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[6]

這次不是在 created() 鉤子 里創建 防抖回調了,而是將 防抖回調 賦給了 methods.debouncedHandler 。

你如果試過 demo,你會發現是有效果的!

問題是,組件使用 export default { ... } 導出的 options 對象,包括方法,會被組件實例重用。

如果網頁中有 2 個以上的組件實例,那么所有的組件都會應用 相同 的防抖函數 methods.debouncedHandler — 這會導致防抖出現故障。

4. 總結

在 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) ,就算執行頻率非常高,內部的回調也能緩沖執行。

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2023-12-18 07:37:17

JavaScript防抖節流

2023-12-21 08:51:37

防抖節流Vue.js

2019-09-02 08:58:27

Python編譯器編程語言

2021-08-03 06:57:36

Js事件節流

2024-10-12 09:33:24

消息隊列多線程并行編程

2024-03-08 08:26:20

防抖節流delay?

2020-10-14 12:29:51

開源圖表 開發

2024-06-14 09:30:58

2017-07-14 10:10:08

Vue.jsMixin

2021-11-19 09:01:09

防抖節流前端

2022-04-01 07:52:42

JavaScript防抖節流

2025-06-19 00:02:00

防抖節流函數

2025-05-09 08:00:00

JavaScript代碼防抖節流

2020-09-14 14:18:05

Vue和React

2017-06-13 10:15:16

iMac蘋果iMac Pro

2017-06-05 14:35:45

2025-05-06 09:35:00

2021-04-17 18:24:04

Vue.js嵌套路由前端

2021-09-07 10:24:36

Vue應用程序Web Workers

2018-11-26 09:20:26

GrailsjQueryDataTables
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久偷人| 91色在线 | 毛片一区二区 | 亚洲成人精品 | 欧美中文字幕在线观看 | 日韩精品一区在线观看 | 中文字幕在线第一页 | 亚洲三区视频 | 91精品国产777在线观看 | 日韩在线免费播放 | www.亚洲一区二区 | 国产在线播放一区二区三区 | 91精品国产91久久久久久 | 久久福利电影 | 一区二区三区四区在线视频 | 日韩三级在线 | 国产精品99久久久久久宅男 | 亚洲精品久 | 日韩一区二区三区在线视频 | 亚洲久久久 | 老外几下就让我高潮了 | 久久久久国产精品一区二区 | 国产精品揄拍一区二区 | 麻豆一区一区三区四区 | 国产精品一区二区三区四区五区 | 色一情一乱一伦一区二区三区 | 欧美日韩国产高清视频 | 亚洲欧美日本国产 | 国产精品毛片久久久久久 | 国产一区二区三区 | 久久亚洲综合 | 成年视频在线观看福利资源 | 欧美精品一区在线发布 | 国产成人精品一区二区 | 国产999精品久久久影片官网 | 国产日韩免费观看 | 一区二区蜜桃 | 亚洲黄色av | 中日av| 精品国产乱码久久久久久88av | 欧美在线观看一区 |