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>
原文地址:https://www.cnblogs.com/cirry/p/13680523.html