Vuejs 2:debounce无法使用手表选项

时间:2017-11-08 06:27:45

标签: javascript vue.js vuejs2 debounce

当我在VueJs中去抖动这个函数时,如果我提供毫秒数作为基元,它可以正常工作。但是,如果我将它作为对道具的参考,它会忽略它。

这是道具的缩写版本:

props : {
    debounce : {
        type : Number,
        default : 500
    }
}

以下是不起作用的监视选项:

watch : {
    term : _.debounce(function () {
        console.log('Debounced term: ' + this.term);
    }, this.debounce)
}

这是一个可以工作的手表选项:

watch : {
    term : _.debounce(function () {
        console.log('Debounced term: ' + this.term);
    }, 500)
}

它怀疑这是一个范围问题,但我不知道如何解决它。如果我按如下方式替换watch方法......:

watch : {
    term : function () {
        console.log(this.debounce);
    }
}

...我在控制台中显示正确的去抖值(500)。

4 个答案:

答案 0 :(得分:1)

这里的主要问题是使用this.debounce作为定义去抖功能的间隔。在运行_.debounce(...)时(编译组件时)该函数尚未附加到Vue,因此this Vue和{{1}将是未定义的。在这种情况下,您需要在创建组件实例后定义监视。 Vue使您能够使用$watch执行此操作。

我建议您将其添加到创建的生命周期处理程序中。

this.debounce

请注意,代码也会在组件被销毁之前调用created(){ this.unwatch = this.$watch('term', _.debounce((newVal) => { console.log('Debounced term: ' + this.term); }, this.debounce)) }, beforeDestroy(){ this.unwatch() } 。这通常由Vue为您处理,但由于代码是手动添加手表,因此代码还需要管理删除手表。当然,您需要添加unwatch作为数据属性。

这是一个有效的例子。



unwatch

console.clear()

Vue.component("debounce",{
  props : {
    debounce : {
      type : Number,
      default : 500
    }
  },
  template:`
    <input type="text" v-model="term">
  `,
  data(){
    return {
      unwatch: null,
      term: ""
    }
  },
  created(){
    this.unwatch = this.$watch('term', _.debounce((newVal) => {
      console.log('Debounced term: ' + this.term);
    }, this.debounce))
  },
  beforeDestroy(){
    this.unwatch()
  }
})

new Vue({
  el: "#app"
})
&#13;
&#13;
&#13;

答案 1 :(得分:0)

&#13;
&#13;
new Vue({
  el: '#term',
  data: function() {
    return {
      term: 'Term',
      debounce: 1000
    }
  },
  watch: {
    term : _.debounce(function () {
        console.log('Debounced term: ' + this.term);
    }, this.debounce)
  }
})
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
<div id="term">
  <input v-model="term">
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

@ Bert答案的另一个变体是在created()中构建观察者的功能,

// SO: Vuejs 2: debounce not working on a watch option

console.clear()

Vue.component("debounce",{
  props : {
    debounce : {
      type : Number,
      default : 500
    }
  },
  template:`
    <div>
      <input type="text" v-model="term">
    </div>
  `,
  data(){
    return {
      term: "",
      debounceFn: null
    }
  },
  created() {
    this.debounceFn = _.debounce( () => {
      console.log('Debounced term: ' + this.term);
    }, this.debounce)
  },
  watch : {
    term : function () {
      this.debounceFn();
    }
  },
})

new Vue({
  el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<div id="app">
  <debounce :debounce="2000"></debounce>
</div>

CodePen

上的示例

答案 3 :(得分:0)

debounced method需要抽象,因为我们需要在每次触发watch时调用相同的函数。如果我们将debounced方法放在Vue computedwatch属性中,则它将更新

const debouncedGetData = _.debounce(getData, 1000);

function getData(val){
  this.newFoo = val;
}

new Vue({
  el: "#app",
  template: `
    <div>
      <input v-model="foo" placeholder="Type something..." />
      <pre>{{ newFoo }}</pre>
    </div>
`,
    data(){
      return {
        foo: '',
        newFoo: ''
      }
    },
    watch:{
      foo(val, prevVal){
        debouncedGetData.call(this, val);
      }
    }
  
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="app"></div>

祝你好运...