我在Vue模板中有一个简单的输入框,我想使用debounce或多或少像这样:

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

然而,在Vue 2中debounce属性已被弃用。建议只说:“使用v-on:输入+第三方反弹功能”。

如何正确地实现它?

我尝试使用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)
}

然后在计算道具中使用过滤键。


当前回答

<template>
  <input type="text" v-model="search" @input="debouncedSearch" />
</template>

<script>
import _ from 'lodash';

export default {
  data() {
    return {
      search: '',
    };
  },
  methods: {
    search() {
      // Perform the search here
      console.log(this.search);
    },
  },
  created() {
    this.debouncedSearch = _.debounce(this.search, 1000);
  },
};
</script>

其他回答

如果你可以将debounce函数的执行移动到某个类方法中,你可以使用utils-decorators lib中的decorator (npm install——save utils-decorators):

import {debounce} from 'utils-decorators';

class SomeService {

  @debounce(500)
  getData(params) {
  }
}

在方法中分配debounce可能会很麻烦。所以不要这样:

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

你可以试试:

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

如果您有一个组件的多个实例,这就会成为一个问题——类似于数据应该是一个返回对象的函数。每个实例都需要自己的debounce函数,如果它们被认为是独立的。

这里有一个问题的例子:

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>

下面是一个Vue 2组件示例,演示了如何使用debounce。

<template>
  <div>
    <v-btn @click="properDebounceMyMethod">Proper debounce</v-btn>
    <v-btn @click="notWorkingDebounceMyMethod">!debounce</v-btn>
    <v-btn @click="myMethod">normal call</v-btn>
  </div>
</template>

<script lang="ts" >
import { defineComponent } from '@vue/composition-api';
import { debounce } from 'lodash';

export default defineComponent({
  name: 'DebounceExample',
  created() {
    // debounce instance method dynamically on created hook
    this.properDebounceMyMethod = debounce(this.properDebounceMyMethod, 500);
  },
  methods: {
    properDebounceMyMethod(){
      this.myMethod();
    },
    notWorkingDebounceMyMethod() {
      debounce(this.myMethod, 500);
    },
    myMethod() {
      console.log('hi from my method');
    },
  }
});
</script>

我也有同样的问题,这里有一个解决方案,没有插件。

因为<input v-model="xxxx">与

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

(源)

我想我可以在xxxx = $event.target.value中为xxxx赋值时设置一个debounce函数

像这样

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

很简单,没有lodash

handleScroll: function() {
  if (this.timeout) 
    clearTimeout(this.timeout); 

  this.timeout = setTimeout(() => {
    // your action
  }, 200); // delay
}