如何使用 Vue.js 在 `keyup` 上使用去抖动

How to use debounce on `keyup` with Vue.js

我正在尝试使用 debounce 函数捕捉用户开始输入和停止输入的情况。我试过了 Lodash and Underscore.js.

On my textArea
                               v-on:keyup="handler($event)"
handler: function(e) {
             this.e = e
             if(this.canPublish) {
                 this.setCanNotPublish()
                 this.doStuff()
             }

             var debounceFunction = _.debounce(this.doneTyping(), 5000)
             debounceFunction(e)

         },

我对此感到非常沮丧。在纯 JavaScript 中,我进行了测试。但是在 Vue.js 它使用 v-on 事件、数据、方法等的地方,我无法让它工作。

方法完成打字

doneTyping: function () {
                console.log('done typing....')
            }

}

方法doStuff

doStuff: function () {
             console.log('started typing....')
         }

预期的行为是:首先用户开始在 textArea 中键入内容,然后启动 doStuff。并且如果用户在短于 5 秒的时间内继续输入,它不会再次触发 doStuff,因为 canPublish 是一个布尔值。接下来用户停止输入,然后去抖功能完成,doneTyping 触发。

以下是消除方法抖动的方法。

doneTyping: _.debounce(function (e) {
    console.log('done typing....')
}, 5000)

那你就这样用吧

handler: function(e) {
    this.e = e
    if(this.canPublish){
        this.setCanNotPublish()
        this.doStuff()
    }

    this.doneTyping() // function is debounced
},

我会使用这两个去抖功能,一个用于开始打字,在前缘触发,一个用于停止打字,在后缘触发。

new Vue({
  el: '#app',
  
  created() {
    this.startedTyping = _.debounce(this.startedTyping, 5000, {
      leading: true,
      trailing: false,
    })
    this.stoppedTyping = _.debounce(this.stoppedTyping, 5000, {
      leading: false,
      trailing: true,
    })
  },
  
  methods: {
    handleKeydown() {
      // This triggers on the leading edge
      this.startedTyping()

      // This triggers on the trailing edge (after 5s)
      this.stoppedTyping()
    },
    
    startedTyping() {
      console.log('started typing')
    },
    
    stoppedTyping() {
      console.log('stopped typing')
    },
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.min.js"></script>

<div id="app">
  <textarea @keydown="handleKeydown"></textarea>
</div>

您的代码是错误的,因为每次调用处理程序时您都在创建一个新的去抖函数。您每次只需要一个去抖函数实例即可。最好在 created 挂钩中创建 debounced 函数。

我经常看到这样的代码:

methods: {
  myDebouncedFunc: _.debounce(function () {
    // Do stuff
  }, 1000)
}

这在技术上没有错,但您可能没有意识到去抖功能将在该组件的所有实例之间共享,这可能不是您想要的。通常最好在 created 挂钩中创建去抖动函数,以便组件的每个实例都有自己独立的去抖动跟踪。