概述:
防抖是指指觸發(fā)事件后锌蓄,在 n 秒內(nèi)函數(shù)只能執(zhí)行一次安岂,如果觸發(fā)事件后在 n 秒內(nèi)又觸發(fā)了事件驾荣,則會(huì)重新計(jì)算函數(shù)延執(zhí)行時(shí)間外构。
防抖應(yīng)用場(chǎng)景:
有一些事件普泡,常見(jiàn)的例如,keypress/keyup审编,onresize撼班,scroll,mousemove ,mousehover 等垒酬,會(huì)被頻繁觸發(fā)(短時(shí)間內(nèi)多次觸發(fā))砰嘁,不做限制的話,有可能一秒之內(nèi)執(zhí)行幾十次勘究、幾百次矮湘,如果在這些函數(shù)內(nèi)部執(zhí)行了其他函數(shù),尤其是執(zhí)行了操作 DOM 的函數(shù)(瀏覽器操作 DOM 是很耗費(fèi)性能的)口糕,那不僅會(huì)浪費(fèi)計(jì)算機(jī)資源板祝,還會(huì)降低程序運(yùn)行速度,甚至造成瀏覽器卡死走净、崩潰券时。這種問(wèn)題顯然是致命的。
如何定義防抖方法:
需要一個(gè) setTimeout 來(lái)輔助實(shí)現(xiàn)伏伯,延遲運(yùn)行需要執(zhí)行的代碼橘洞。如果方法多次觸發(fā),則把上次記錄的延遲執(zhí)行代碼用 clearTimeout 清掉说搅,重新開(kāi)始計(jì)時(shí)炸枣。若計(jì)時(shí)期間事件沒(méi)有被重新觸發(fā),等延遲時(shí)間計(jì)時(shí)完畢弄唧,則執(zhí)行目標(biāo)代碼适肠。
const debounce = function debounce(fn, delay) {
var timeoutID = null;
return function () {
clearTimeout(timeoutID);
var args = arguments;
var that = this;
timeoutID = setTimeout(function () {
fn.apply(that, args);
}, delay);
};
};
VUE中method和watch區(qū)別
1.watch:watch是以Vue的依賴追蹤機(jī)制為基礎(chǔ)的,它試圖處理當(dāng)某一個(gè)數(shù)據(jù)(稱它為依賴數(shù)據(jù))發(fā)生變化的時(shí)候候引,所有依賴這個(gè)數(shù)據(jù)的“相關(guān)”數(shù)據(jù)“自動(dòng)”發(fā)生變化侯养,也就是自動(dòng)調(diào)用相關(guān)的函數(shù)去實(shí)現(xiàn)數(shù)據(jù)的變動(dòng)。
2.對(duì)methods:methods里面是用來(lái)定義函數(shù)的澄干,很顯然逛揩,它需要手動(dòng)調(diào)用才能執(zhí)行磅氨。而不像watch和computed那樣祟同,“自動(dòng)執(zhí)行”預(yù)先定義的函數(shù)。
通過(guò)method實(shí)現(xiàn)的防抖:
<template>
<div>
<input type="text" v-model="input_text" />
<button @click="input">點(diǎn)我</button>
<br />
{{ debounced_input }}
</div>
</template>
<script>
const debounce = function debounce(fn, delay) {
var timer = null;
return function () {
clearTimeout(timer);
var args = arguments;
var that = this;
timer = setTimeout(function () {
fn.apply(that, args);
}, delay);
};
};
export default {
name: 'test_debounce',
data() {
return {
input_text: "",
debounced_input: ""
};
},
methods:{
input: debounce(function () {
this.debounced_input = this.$data.input_text;
}, 500)
},
};
</script>
通過(guò)watch實(shí)現(xiàn)的防抖
<template>
<div>
<input type="text" v-model="input_text" />
<br />
{{ debounced_input }}
</div>
</template>
<script>
const debounce = function debounce(fn, delay) {
var timer = null;
return function () {
clearTimeout(timer);
var args = arguments;
var that = this;
timer = setTimeout(function () {
fn.apply(that, args);
}, delay);
};
};
export default {
name: 'test_debounce',
data() {
return {
input_text: "",
debounced_input: ""
};
},
watch: {
input_text: debounce(function (new_value) {
this.debounced_input = new_value;
}, 500)
}
};
</script>