簡體   English   中英

Vuejs 2:debounce 不適用於監視選項

[英]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 computedwatch屬性中,它將每次都更新

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM