今天我中遇到了一個這樣的場景,發現觸發複用的自定義元件中新增了防抖的函式,發現只執行了一次,並沒有如預期的那樣每個元件內的函式都執行一次。
一開始以為是沒有同步賦值,檢查了一下沒問題,才把關注點轉移到 debounce
上面。移除防抖之後果然解決問題了,但防抖又不能去去掉。
所以查了一下相關的問題,發現是因為多個元件例項是共享同一個預置防抖的函式,並不是相互獨立的。
一直以來都是直接如 Vue
檔案中演示的這樣來寫的,加上請求介面就會是下面這樣:
import debounce from "lodash.debounce";
import { remoteSearchAPI } from 'xxxx';
export default {
// ...
methods: {
remoteMethod: debounce(function (value = "") {
const params = {
keywords: value,
};
this.fetching = true;
remoteSearchAPI(params)
.then((res) => {
// ...
})
.finally(() => {
this.fetching = false;
});
}, 350, { maxWait: 1000 }),
},
};
這樣寫的話就會有一個問題:
這種方法對於被重用的元件來說是有問題的,因為這個預置防抖的函式是 有狀態的:它在執行時維護著一個內部狀態。如果多個元件例項都共享這同一個預置防抖的函式,那麼它們之間將會互相影響。
響應式基礎 | Vue.js
那麼如何解決這個問題呢?
Vue的檔案中也給出了相應的解決方案。
要保持每個元件例項的防抖函式都彼此獨立,我們可以改為在 created
生命週期鉤子中建立這個預置防抖的函式:
export default {
created() {
// 每個例項都有了自己的預置防抖的處理函式
this.debouncedClick = _.debounce(this.click, 500)
},
unmounted() {
// 最好是在元件解除安裝時
// 清除掉防抖計時器
this.debouncedClick.cancel()
},
methods: {
click() {
// ... 對點選的響應 ...
}
}
}
參考資源
vue 踩坑小記 - 如何正確的使用 debounce
#有狀態方法 響應式基礎 | Vue.js
本文參與了SegmentFault 思否寫作挑戰賽,歡迎正在閱讀的你也加入。