[英]Vuejs 2: debounce not working on a watch option
當我在 VueJs 中對這個函數進行去抖動時,如果我提供毫秒數作為原語,它就可以正常工作。 但是,如果我提供它作為對道具的引用,它會忽略它。
這是道具的縮寫版本:
props : {
debounce : {
type : Number,
default : 500
}
}
這是不起作用的監視選項:
watch : {
term : _.debounce(function () {
console.log('Debounced term: ' + this.term);
}, this.debounce)
}
這是一個可以工作的手表選項:
watch : {
term : _.debounce(function () {
console.log('Debounced term: ' + this.term);
}, 500)
}
它懷疑這是一個范圍問題,但我不知道如何解決它。 如果我按如下方式替換 watch 方法......:
watch : {
term : function () {
console.log(this.debounce);
}
}
...我得到正確的去抖值(500)出現在控制台中。
@Bert 答案的另一個變體是在created()
中構建觀察者的函數,
// SO: Vuejs 2: debounce not working on a watch option console.clear() Vue.component("debounce",{ props : { debounce : { type : Number, default : 500 } }, template:` <div> <input type="text" v-model="term"> </div> `, data(){ return { term: "", debounceFn: null } }, created() { this.debounceFn = _.debounce( () => { console.log('Debounced term: ' + this.term); }, this.debounce) }, watch : { term : function () { this.debounceFn(); } }, }) new Vue({ el: "#app" })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> <div id="app"> <debounce :debounce="2000"></debounce> </div>
CodePen上的示例
這里的主要問題是在定義去抖函數時使用this.debounce
作為間隔。 在_.debounce(...)
運行時(當組件正在編譯時),該函數尚未附加到 Vue,因此this
不是Vue 並且this.debounce
將是未定義的。 在這種情況下,您需要在創建組件實例后定義手表。 Vue 使您能夠使用$watch來做到這一點。
我建議您將其添加到創建的生命周期處理程序中。
created(){
this.unwatch = this.$watch('term', _.debounce((newVal) => {
console.log('Debounced term: ' + this.term);
}, this.debounce))
},
beforeDestroy(){
this.unwatch()
}
請注意,代碼還在組件被銷毀之前調用unwatch
。 這通常由 Vue 為您處理,但由於代碼是手動添加手表,因此代碼還需要管理刪除手表。 當然,您需要將unwatch
添加為數據屬性。
這是一個工作示例。
console.clear() Vue.component("debounce",{ props : { debounce : { type : Number, default : 500 } }, template:` <input type="text" v-model="term"> `, data(){ return { unwatch: null, term: "" } }, created(){ this.unwatch = this.$watch('term', _.debounce((newVal) => { console.log('Debounced term: ' + this.term); }, this.debounce)) }, beforeDestroy(){ this.unwatch() } }) new Vue({ el: "#app" })
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> <script src="https://unpkg.com/vue@2.4.2"></script> <div id="app"> <debounce :debounce="250"></debounce> </div>
new Vue({ el: '#term', data: function() { return { term: 'Term', debounce: 1000 } }, watch: { term : _.debounce(function () { console.log('Debounced term: ' + this.term); }, this.debounce) } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script> <div id="term"> <input v-model="term"> </div>
debounced method
需要抽象,因為我們需要在每次觸發watch
時調用相同的函數。 如果我們將debounced
方法放在Vue
computed
或watch
屬性中,它將每次都更新。
const debouncedGetData = _.debounce(getData, 1000); function getData(val){ this.newFoo = val; } new Vue({ el: "#app", template: ` <div> <input v-model="foo" placeholder="Type something..." /> <pre>{{ newFoo }}</pre> </div> `, data(){ return { foo: '', newFoo: '' } }, watch:{ foo(val, prevVal){ debouncedGetData.call(this, val); } } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="app"></div>
祝你好運...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.