搜尋

首頁  >  問答  >  主體

Vue3中的防手震實作方法

<p>我有一個過濾輸入框,並且想要過濾一個項目清單。清單很大,所以我想使用防手震來延遲應用過濾器,直到用戶停止輸入,以提高用戶體驗。這是我的輸入框,它與用於過濾列表的filterText綁定。 </p> <pre class="brush:php;toolbar:false;"><input type="text" v-model="state.filterText" /></pre>
P粉055726146P粉055726146461 天前633

全部回覆(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
  • 取消回覆