Vue3中的防抖实现方法
P粉055726146
P粉055726146 2023-08-24 12:07:02
0
2
642
<p>我有一个过滤输入框,并且想要过滤一个项目列表。列表很大,所以我想使用防抖来延迟应用过滤器,直到用户停止输入,以提高用户体验。这是我的输入框,它与用于过滤列表的filterText绑定。</p> <pre class="brush:php;toolbar:false;"><input type="text" v-model="state.filterText" /></pre>
P粉055726146
P粉055726146

全部回复(2)
P粉879517403

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

首先创建带有指令的文件,例如。 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自动更新,直到您停止输入或超时时间到期(可以在指令的值中设置)。 希望这样清楚明了。

P粉550257856

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

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 })"
    />
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板