vue+element-自定義指令,防止重複提交及重複發送http請求;節流throttle與防抖debounce舉例說明

  • 方法一、控制標籤 
全局directive的寫法
// 提交以後禁用按鈕一段時間,防止重複提交
import Vue from 'vue';
Vue.directive('noMoreClick', {
  inserted(el, binding) {
    el.addEventListener('click', e => {
      el.classList.add('is-disabled');
      el.disabled = true;
      setTimeout(() => {
        el.disabled = false;
        el.classList.remove('is-disabled');
      }, 3000)
    })
  }
});
局部directive的寫法
directives:{
      noMoreClick: {
        inserted(el, binding) {
          el.addEventListener('click', () => {
            el.classList.add('is-disabled');
            el.disabled = true;
            setTimeout(() => {
              el.disabled = false;
              el.classList.remove('is-disabled');
            }, 2000)
          })
        }
      }
    },

使用:

<el-button size="small" class="clear-btn m-t-sm m-b-sm" @click="resetForm" v-no-more-click>
  Confirm
</el-button>
  •  方法二、控制JS

使用這個,首先應該對Lodash.js有一定的瞭解,(打開鏈接,搜索debounce即可查看相應文檔

_.debounce(func, [wait=0], [options={}])

創建一個 debounced(防抖動)函數,該函數會從上一次被調用後,延遲 wait 毫秒後調用 func 方法。 debounced(防抖動)函數提供一個 cancel 方法取消延遲的函數調用以及 flush 方法立即調用。 可以提供一個 options(選項) 對象決定如何調用 func 方法,options.leading 與|或 options.trailing 決定延遲前後如何觸發(愚人碼頭注:是 先調用後等待 還是 先等待後調用)。 func 調用時會傳入最後一次提供給 debounced(防抖動)函數 的參數。 後續調用的 debounced(防抖動)函數返回是最後一次 func 調用的結果。 

methods:{   
    // 觸發事件
     clickMe(){
		this.getData('111');
	},
	getData: _.debounce(function(value){
		console.log(value);//2秒後打印'111'
	},2000)
}

 

防抖動原理:

  • 1、debounce
function debounce(fn,delay){
 
    var delay=delay||200;
    var timer;
    return function(){
        var th=this;
        var args=arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer=setTimeout(function () {
                timer=null;
                fn.apply(th,args);
        }, delay);
    };
}

我們調用debounce的時候,它運行返回一個function,這個function使用外面的局部變量delay和timer。這個返回的function纔是事件執行的回調。每次執行的時候判斷timer是否有值,有值則clearTimeout清空定時器,並且重新開啓定時器,直到delay時間內沒有觸發事件時纔會真正執行事件的回調。

  • 2、throttle實現
function throttle(fn,interval){
    var last;
    var timer;
    var interval=interval||200;
    return function(){
        var th=this;
        var args=arguments;
        var now=+new Date();
        if(last&&now-last<interval){
            clearTimeout(timer);
            timer=setTimeout(function(){
                last=now;
                fn.apply(th,args);
            },interval);
        }else{
            last=now;
            fn.apply(th,args);
        }
    }
}

使用方法跟debounce一樣。代碼邏輯也類似。在觸發時超過間隔時間interval ms則執行。否則不執行。if判斷中的setTimeout是保證最後一次事件觸發後能夠調用,所以每次執行沒到間隔時間時先清除timer,再重新啓動timer。而在達到間隔時間時執行函數。

  • 防抖動與節流的區別

防抖動就是,在多次觸發時(不間斷點擊N秒),點擊停止3秒後觸發函數 (常用於keydown事件上驗證用戶名等)

  // 函數防抖
  let timer = false;
  document.getElementById("throttle").onclick = function(){
    clearTimeout(timer);
    timer = setTimeout(()=>{
      console.log("執行買的http請求");
      console.log(timer);
    },2000)
  };

節流是,在多次觸發時(不間斷點擊N秒),每隔3秒觸發一次函數,常用於resize改變佈局,scroll滾動事件等

  // 函數節流
  let flag = true;
  document.getElementById("throttle").onclick = function(){
    console.log("買");
    if(!flag){
      return
    }
    flag = false;
    setTimeout(()=>{
      flag = true;
      console.log("執行買的http請求")
    },2000)
  };

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章