1. 程式人生 > 實用技巧 >vue中實現節流指令

vue中實現節流指令

utils.js檔案

export function debounce(func , wait , immediate = true){
  // 定義一個timeout計時器
  let timeout
  return function (){
    // 如果每次進入函式的時候timeout有值,說明等待時間還沒有過,不執行函式,清空timeout
    // 如果沒有timeout,則說明過了等待期,可以執行函式
    if(timeout) clearTimeout(timeout)
    // 預設立即執行方法,延後執行的話,會讓人感覺有卡頓
    if(immediate){
      // 定義現在是否能執行
      let now = !timeout
      if(now) func.apply(this, arguments)
      // 不論timeout有沒有值,都重新給timeout新新增一個定時器
      // 等待wait時間後,將timeout設為null,代表可以繼續執行次function
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
    }else{
      // 如果不是立即執行此函式,則在等待wait時間後執行方法
      timeout = setTimeout(()=>{
        func.apply(this, arguments)
      }, wait)
    }
  }
}

direction.js檔案

import Vue from 'vue'
import {debounce} from './utils'
// 定義一個名為debounce的指令
Vue.directive('debounce', {
  // 繫結的值為el,和binding
  // binding的值為指令繫結的值,binding中有哪些值,可以去vue官網中檢視自定義指令
  bind(el, binding){
    let execFunc
    // 在函式傳參與不傳參呼叫的時候,打印出來的binding.value是不同的
    // 列印binding.value可以幫助理解為什麼有傳參和不傳參的區別
    console.log(binding.value)
    if(binding.value instanceof Array){
      // 函式傳參
      const [func , time = 500] = binding.value
      execFunc = debounce(func, time)
    }else{
      // 函式不傳參
      console.log('函式不傳參')
      execFunc = debounce(binding.value, 500)
    }
    el.addEventListener('click', execFunc)
  }
})

函式不傳參列印為:

函式傳參:

在vue中使用:

傳參使用方式:

<el-button  v-debounce="() => batchDelete('delete')">{{ $t('common.delete') }}</el-button>

如果不這麼寫的話,會返回函式執行完之後的返回值。

不傳參使用方式:

<el-button class="lb-btn lb-btn-primary" icon="el-icon-delete" v-debounce="batchDelete">
            {{ $t('common.delete') }}
          </el-button>