Cómo implementar debounce en Vue2?


Tengo un cuadro de entrada simple en una plantilla de Vue y me gustaría usar debounce más o menos así:

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

Sin embargo, la propiedad debounce ha sido obsoleta en Vue 2. La recomendación solo dice: "use v-on: input + 3rd party debounce function".

¿Cómo lo implementas correctamente?

He intentado implementarlo usando lodash, v-on: input y v-model , pero me pregunto si es posible prescindir del extra variable.

En la plantilla:

<input type="text" v-on:input="debounceInput" v-model="searchInput">

En la escritura:

data: function () {
  return {
    searchInput: '',
    filterKey: ''
  }
},

methods: {
  debounceInput: _.debounce(function () {
    this.filterKey = this.searchInput;
  }, 500)
}

El filterkey se usa más tarde en computed props.

Author: Bert, 2017-02-13

4 answers

Estoy usando debounce paquete NPM e implementado así:

<input @input="debounceInput">

methods: {
    debounceInput: debounce(function (e) {
      this.$store.dispatch('updateInput', e.target.value)
    }, config.debouncers.default)
}

Usando lodash y el ejemplo de la pregunta, la implementación se ve así:

<input v-on:input="debounceInput">

methods: {
  debounceInput: _.debounce(function (e) {
    this.filterKey = e.target.value;
  }, 500)
}
 66
Author: Primoz Rome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-14 22:56:34

Asignar debounce en methods puede ser un problema. Así que en lugar de esto:

// Bad
methods: {
  foo: _.debounce(function(){}, 1000)
}

Puede intentar:

// Good
created () {
  this.foo = _.debounce(function(){}, 1000);
}

Se convierte en un problema si tiene varias instancias de un componente, similar a la forma en que data debería ser una función que devuelve un objeto. Cada instancia necesita su propia función de debounce si se supone que deben actuar de forma independiente. Ver Ejemplo

 11
Author: bendytree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-10 19:22:57

Tenga en cuenta que publiqué esta respuesta antes de la respuesta aceptada. No correcto. Es solo un paso adelante de la solución en el pregunta. He editado la pregunta aceptada para mostrar tanto la implementación del autor como la implementación final que había utilizado.


Basado en los comentarios y el documento de migración vinculado , he hecho algunos cambios en el código:

En la plantilla:

<input type="text" v-on:input="debounceInput" v-model="searchInput">

En el script:

watch: {
  searchInput: function () {
    this.debounceInput();
  }
},

Y el método que establece que la tecla de filtro permanece igual:

methods: {
  debounceInput: _.debounce(function () {
    this.filterKey = this.searchInput;
  }, 500)
}

Esto parece que hay una llamada menos (solo la v-model, y no la v-on:input).

 3
Author: sm4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-25 22:01:28

Si necesita un enfoque muy minimalista para esto, hice uno (originalmente bifurcado de vuejs-consejos para también apoyar IE) que está disponible aquí: https://www.npmjs.com/package/v-debounce

Uso:

<input v-model.lazy="term" v-debounce="delay" placeholder="Search for something" />

Luego en tu componente:

<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>
 1
Author: Coreus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-15 10:16:39