Eu tenho uma caixa de entrada simples em um modelo do Vue e gostaria de usar o debounce mais ou menos assim:
<input type="text" v-model="filterKey" debounce="500">
No entanto, a debounce
propriedade foi descontinuada no Vue 2 . A recomendação diz apenas: "use v-on: input + função de debounce de terceiros".
Como você o implementa corretamente?
Eu tentei implementá-lo usando lodash , v-on: input e v-model , mas estou pensando se é possível fazer isso sem a variável extra.
No modelo:
<input type="text" v-on:input="debounceInput" v-model="searchInput">
No script:
data: function () {
return {
searchInput: '',
filterKey: ''
}
},
methods: {
debounceInput: _.debounce(function () {
this.filterKey = this.searchInput;
}, 500)
}
A chave de filtro é então usada mais tarde em computed
adereços.
vue.js
vuejs2
debouncing
MartinTeeVarga
fonte
fonte
Respostas:
Estou usando o pacote debounce NPM e implementado assim:
Usando lodash e o exemplo na pergunta, a implementação se parece com isso:
fonte
v-model=your_input_variable
à entrada e no seu vuedata
. Então você não contar come.target
, mas usar Vue para que você possa acessarthis.your_input_variable
em vez dee.target.value
this
dentro da função.Atribuir debounce
methods
pode ser um problema. Então, em vez disso:Você pode tentar:
Torna-se um problema se você tiver várias instâncias de um componente - semelhante à maneira como
data
deve ser uma função que retorna um objeto. Cada instância precisa de sua própria função de rejeição, se eles devem agir de forma independente.Aqui está um exemplo do problema:
fonte
data()
então.atualizado em 2020
Opção 1: reutilizável, sem deps
(Recomendado se necessário mais de uma vez no seu projeto)
helpers.js
Component.vue
Codepen
Opção 2: no componente, sem deps
(Recomendado se usar uma vez ou em um projeto pequeno)
Component.vue
Codepen
fonte
Muito simples sem lodash
fonte
destroyed() { clearInterval(this.timeout) }
para não ter um tempo limite após destruído.Eu tive o mesmo problema e aqui está uma solução que funciona sem plugins.
Como
<input v-model="xxxx">
é exatamente o mesmo que(fonte)
Eu imaginei que poderia definir uma função de debounce na atribuição de xxxx em
xxxx = $event.target.value
como isso
métodos:
fonte
@input="update_something"
ação, chame-o depoisthat.xxx = val
that.update_something();
debounceSearch: function(val) { if (this.search_timeout) clearTimeout(this.search_timeout); var that=this; this.search_timeout = setTimeout(function() { that.thread_count = val; that.update_something(); }, 500); },
Com base nos comentários e no documento de migração vinculado , fiz algumas alterações no código:
No modelo:
No script:
E o método que define a chave de filtro permanece o mesmo:
Parece que há menos uma chamada (apenas a
v-model
, e não av-on:input
).fonte
debounceInput()
duas vezes para cada alteração?v-on:
detectará as alterações de entrada e rejeitará chamadas, E como o modelo é vinculado, a função de relógio do searchInput TAMBÉM chamarádebounceInput
... certo?Se você precisar de uma abordagem muito minimalista, criei uma (originalmente bifurcada no vuejs-tips para também oferecer suporte ao IE) disponível aqui: https://www.npmjs.com/package/v-debounce
Uso:
Então no seu componente:
fonte
Caso você precise aplicar um atraso dinâmico com a
debounce
função do lodash :E o modelo:
NOTA: no exemplo acima, fiz um exemplo de entrada de pesquisa que pode chamar a API com um atraso personalizado, fornecido em
props
fonte
Embora praticamente todas as respostas aqui já estejam corretas, se alguém estiver em busca de uma solução rápida, tenho uma diretiva para isso. https://www.npmjs.com/package/vue-lazy-input
Aplica-se a @input e v-model, suporta componentes personalizados e elementos DOM, debounce e throttle.
fonte
Se você estiver usando o Vue, também poderá usar em
v.model.lazy
vez de,debounce
mas lembre-sev.model.lazy
se de que nem sempre funcionará, pois o Vue o limita para componentes personalizados.Para componentes personalizados, você deve usar
:value
junto com@change.native
<b-input :value="data" @change.native="data = $event.target.value" ></b-input>
fonte
Se você pudesse mover a execução da função debounce para algum método de classe, poderia usar um decorador a partir da utils-decorators lib (
npm install --save utils-decorators
):fonte
Podemos fazer isso usando poucas linhas de código JS:
Solução simples! Trabalho perfeito! Espero que seja útil para vocês.
fonte
decor-propriedade-vue
fonte