首页  >  问答  >  正文

Vue3中的防抖实现方法

<p>我有一个过滤输入框,并且想要过滤一个项目列表。列表很大,所以我想使用防抖来延迟应用过滤器,直到用户停止输入,以提高用户体验。这是我的输入框,它与用于过滤列表的filterText绑定。</p> <pre class="brush:php;toolbar:false;"><input type="text" v-model="state.filterText" /></pre>
P粉055726146P粉055726146392 天前582

全部回复(2)我来回复

  • P粉879517403

    P粉8795174032023-08-25 11:20:55

    嗨,第一次在这里回答问题,所以请尽情纠正我的答案,我会非常感激。 我认为最漂亮、最轻量的解决方案是在全局创建一个指令,您可以在所有表单中随意使用。

    首先创建带有指令的文件,例如。 debouncer.js

    然后创建防抖函数

        //debouncer.js
        /*
          这是一个典型的防抖函数,它接收“callback”和等待发出事件的时间
        */
        function debouncer (fn, delay) {
            var timeoutID = null
            return function () {
              clearTimeout(timeoutID)
              var args = arguments
              var that = this
              timeoutID = setTimeout(function () {
                fn.apply(that, args)
              }, delay)
            }
          }
    
        /*
          此函数接收指令将设置在其中的元素和设置在其中的值
          如果值已更改,则重新绑定事件
          它具有默认超时时间为500毫秒
        */
        module.exports = function debounce(el, binding) {
          if(binding.value !== binding.oldValue) {
            el.oninput = debouncer(function(){
              el.dispatchEvent(new Event('change'))
            }, parseInt(binding.value) || 500)
          }
        }
    

    在定义了这个文件之后,您可以转到您的main.js导入它并使用导出的函数。

        //main.js
        import { createApp } from 'vue'
        import debounce from './directives/debounce' // 导入的文件
        
        const app = createApp(App)
    
        //定义指令
        app.directive('debounce', (el,binding) => debounce(el,binding))
    
        app.mount('#app')
    

    完成了,当您想要在输入框中使用指令时,只需像这样操作,无需导入或其他任何操作。

        //Component.vue
        <input
           :placeholder="按名称筛选"
           v-model.lazy="filter.value" v-debounce="400"
        />
    

    如果您选择以这种方式进行操作,v-model.lazy指令非常重要,因为默认情况下,它会在输入事件上更新绑定的属性,但设置这个指令会使其等待更改事件,而这是我们在防抖函数中发出的事件。这样做将停止v-model自动更新,直到您停止输入或超时时间到期(可以在指令的值中设置)。 希望这样清楚明了。

    回复
    0
  • P粉550257856

    P粉5502578562023-08-25 10:05:26

    我没有找到满意的解决方案,因为我想在模板中看到我的绑定,所以我决定分享我的解决方案。我编写了一个简单的防抖函数,并使用以下语法绑定行为:

    setup() {
    ...
    
      function createDebounce() {
        let timeout = null;
        return function (fnc, delayMs) {
          clearTimeout(timeout);
          timeout = setTimeout(() => {
            fnc();
          }, delayMs || 500);
        };
      }
    
      return {
        state,
        debounce: createDebounce(),
      };
    },
    

    而模板语法如下:

        <input
          type="text"
          :value="state.filterText"
          @input="debounce(() => { state.filterText = $event.target.value })"
        />
    

    回复
    0
  • 取消回复