web-dev-qa-db-ja.com

Vue2でデバイスを実装する方法

私はVueテンプレートに簡単な入力ボックスを持っています、そして私はこのように多かれ少なかれデバウンスを使用したいと思います:

<input type="text" v-model="filterKey" debounce="500">

しかしdebounceプロパティは Vue 2では廃止予定 です。 「v-on:input +サードパーティのデバウンス機能を使用する」という推奨のみが推奨されています。

どのように正しく実装しますか?

lodashv-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小道具で後で使用されます。

81
sm4

私は 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)
}
109
Primoz Rome

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>
35
bendytree

私は同じ問題を抱えていて、これはプラグインなしで働きました

<input v-model="xxxx">はまったく同じですので

<input
   v-bind:value="xxxx"
   v-on:input="xxxx = $event.target.value"
>

(source)

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);
},
7
stallingOne

私はこの答えを受け入れた答えの前に投稿したことに注意してください。それは正しくありません。それは問題の解決策からの一歩前進です。私は、受け入れられた質問を編集して、著者の実装と私が使用した最後の実装の両方を示しました。


コメントと リンクされた移行ドキュメント に基づいて、私はコードにいくつかの変更を加えました:

テンプレート内:

<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のみ)。

3
sm4

Lodashなしでとてもシンプル

  handleScroll: function() {
   if (this.timeout) clearTimeout(this.timeout); 
     this.timeout = setTimeout(() => {
       // your action
     }, 200);
  }
3
pshx

あなたがこれに非常にミニマルなアプローチを必要とするならば、私はここで利用可能であるものを作りました(もともと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>
2
Coreus

再利用可能で、学位はありません。

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>

小さなデバウンス

1
digout

Vueを使用している場合、debounceの代わりにv.model.lazyを使用することもできますが、v.model.lazyはVueがカスタムコンポーネント用に制限しているため、常に機能するとは限らないことに注意してください。

カスタムコンポーネントの場合は:value@change.nativeと共に使用する必要があります。

<b-input :value="data" @change.native="data = $event.target.value" ></b-input>

0
Amir Khadem

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を呼び出すことができる検索入力の例を作成しました

0
roli roli

JSコードを数行使用することでこれを実行できます。

if(typeof window.LIT !== 'undefined') {
      clearTimeout(window.LIT);
}

window.LIT = setTimeout(() => this.updateTable(), 1000);

シンプルなソリューション!ワークパーフェクト!皆さんに役立つことを願っています。

0
Tanvir Hasan