私はVueテンプレートに簡単な入力ボックスを持っています、そして私はこのように多かれ少なかれデバウンスを使用したいと思います:
<input type="text" v-model="filterKey" debounce="500">
しかしdebounce
プロパティは Vue 2では廃止予定 です。 「v-on:input +サードパーティのデバウンス機能を使用する」という推奨のみが推奨されています。
どのように正しく実装しますか?
lodash、v-on:inputを使って実装しようとしました。 )とv-modelですが、余分な変数を使わなくても可能かどうか疑問に思います。
テンプレート内:
<input type="text" v-on:input="debounceInput" v-model="searchInput">
スクリプトの中で:
data: function () {
return {
searchInput: '',
filterKey: ''
}
},
methods: {
debounceInput: _.debounce(function () {
this.filterKey = this.searchInput;
}, 500)
}
その後、フィルタキーはcomputed
小道具で後で使用されます。
私は debounce NPMパッケージを使用しており、このように実装されています。
<input @input="debounceInput">
methods: {
debounceInput: debounce(function (e) {
this.$store.dispatch('updateInput', e.target.value)
}, config.debouncers.default)
}
lodash と問題の例を使用すると、実装は次のようになります。
<input v-on:input="debounceInput">
methods: {
debounceInput: _.debounce(function (e) {
this.filterKey = e.target.value;
}, 500)
}
methods
にデバウンスを割り当てるのは面倒です。だからこれの代わりに:
// Bad
methods: {
foo: _.debounce(function(){}, 1000)
}
あなたが試すことができます:
// Good
created () {
this.foo = _.debounce(function(){}, 1000);
}
コンポーネントのインスタンスが複数ある場合は問題になります - data
がオブジェクトを返す関数であるべき方法と同じです。それらが独立して行動することになっている場合、各インスタンスはそれ自身のデバウンス機能を必要とします。
これが問題の例です。
Vue.component('counter', {
template: '<div>{{ i }}</div>',
data: function(){
return { i: 0 };
},
methods: {
// DON'T DO THIS
increment: _.debounce(function(){
this.i += 1;
}, 1000)
}
});
new Vue({
el: '#app',
mounted () {
this.$refs.counter1.increment();
this.$refs.counter2.increment();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<div id="app">
<div>Both should change from 0 to 1:</div>
<counter ref="counter1"></counter>
<counter ref="counter2"></counter>
</div>
私は同じ問題を抱えていて、これはプラグインなしで働きました。
<input v-model="xxxx">
はまったく同じですので
<input
v-bind:value="xxxx"
v-on:input="xxxx = $event.target.value"
>
xxxx = $event.target.value
にxxxxを代入することでデバウンス関数を設定できると考えました
このような
<input
v-bind:value="xxxx"
v-on:input="debounceSearch($event.target.value)"
>
メソッド:
debounceSearch(val){
if(search_timeout) clearTimeout(search_timeout);
var that=this;
search_timeout = setTimeout(function() {
that.xxxx = val;
}, 400);
},
私はこの答えを受け入れた答えの前に投稿したことに注意してください。それは正しくありません。それは問題の解決策からの一歩前進です。私は、受け入れられた質問を編集して、著者の実装と私が使用した最後の実装の両方を示しました。
コメントと リンクされた移行ドキュメント に基づいて、私はコードにいくつかの変更を加えました:
テンプレート内:
<input type="text" v-on:input="debounceInput" v-model="searchInput">
スクリプト内:
watch: {
searchInput: function () {
this.debounceInput();
}
},
そして、フィルタキーを設定する方法は同じです。
methods: {
debounceInput: _.debounce(function () {
this.filterKey = this.searchInput;
}, 500)
}
これは、呼び出しが1つ少なくなったように見えます(v-model
ではなくv-on:input
のみ)。
Lodashなしでとてもシンプル
handleScroll: function() {
if (this.timeout) clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
// your action
}, 200);
}
あなたがこれに非常にミニマルなアプローチを必要とするならば、私はここで利用可能であるものを作りました(もともとIEをサポートするためにvuejs-tipsから分岐された): https://www.npmjs.com/package/v-debounce
使用法:
<input v-model.lazy="term" v-debounce="delay" placeholder="Search for something" />
それからあなたのコンポーネントで:
<script>
export default {
name: 'example',
data () {
return {
delay: 1000,
term: '',
}
},
watch: {
term () {
// Do something with search term after it debounced
console.log(`Search term changed to ${this.term}`)
}
},
directives: {
debounce
}
}
</script>
再利用可能で、学位はありません。
helpers.js
module.exports = 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
<script>
import debounce from './helpers'
export default {
data () {
return {
input: '',
debouncedInput: ''
}
},
watch: {
input: debounce(function (newVal) {
this.debouncedInput = newVal
}, 500)
}
}
</script>
( 小さなデバウンス )
Vueを使用している場合、debounce
の代わりにv.model.lazy
を使用することもできますが、v.model.lazy
はVueがカスタムコンポーネント用に制限しているため、常に機能するとは限らないことに注意してください。
カスタムコンポーネントの場合は:value
を@change.native
と共に使用する必要があります。
<b-input :value="data" @change.native="data = $event.target.value" ></b-input>
Lodashのdebounce
関数で動的遅延を適用する必要がある場合:
props: {
delay: String
},
data: () => ({
search: null
}),
created () {
this.valueChanged = debounce(function (event) {
// Here you have access to `this`
this.makeAPIrequest(event.target.value)
}.bind(this), this.delay)
},
methods: {
makeAPIrequest (newVal) {
// ...
}
}
およびテンプレート:
<template>
//...
<input type="text" v-model="search" @input="valueChanged" />
//...
</template>
注:上記の例では、props
で提供されるカスタム遅延でAPIを呼び出すことができる検索入力の例を作成しました
JSコードを数行使用することでこれを実行できます。
if(typeof window.LIT !== 'undefined') {
clearTimeout(window.LIT);
}
window.LIT = setTimeout(() => this.updateTable(), 1000);
シンプルなソリューション!ワークパーフェクト!皆さんに役立つことを願っています。