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>