页面中的使用非常简单
给需要延时或者节流的函数绑定v-指定就可以
.isImmediate为修饰符 判断延时模式
在main.js使用Vue自定义指令封装功能
import Vue from 'vue'
import { debounce, throttle } from '../utils/util'
Vue.directive('debounce', {
bind(el, binding) {
let isImmediate = null
isImmediate = binding.modifiers.isImmediate ? true : false //命令修饰符
const executeFunction = debounce(binding.value, 1000, isImmediate)
// 点击触发 这个可以根据自己需要更改 input/change
el.addEventListener('click', executeFunction)
// 取消延时立即触发 同理 可根据自己需要更改触发方式
el.addEventListener('mouseleave', executeFunction.cancel)
}
})
Vue.directive('throttle', {
bind(el, binding) {
const executeFunction = throttle(binding.value, 2000)
el.addEventListener('click', executeFunction)
el.addEventListener('mouseleave', executeFunction.cancel)
}
})
在utils中 封装函数
export function debounce(fn, wait, isImmediate = false) {
let timer = null, // 定时器
flag = null, // 是否可以执行
resultFunc = null // 返回函数
// 立即执行一次在延时执行版本
if (isImmediate) {
resultFunc = function () {
if (flag) {
timer && clearTimeout(timer);
fn.apply(this, arguments);
flag = false
// 确保下次可以立即执行
setTimeout(() => {
flag = true
}, wait)
} else {
timer && clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments)
flag = true
}, wait)
}
}
// 取消等待立即执行
resultFunc.cancel = function () {
clearTimeout(timer);
fn.apply(this, arguments)
flag = true;
}
} else {
// 不立即执行
// 例如:用户在输入框中输入字符,最终间隔超过2秒后,才执行补全查询
resultFunc = function () {
timer && clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments)
}, wait)
}
// 取消等待立即执行
resultFunc.cancel = function () {
console.log("立即取消等待");
clearTimeout(timer);
fn.apply(this, arguments)
}
}
return resultFunc;
}
export const throttle = function (fn, delay, isImmediate = false) {
let timer = null, // 定时器
prevTime = null, // 上一次执行时间
resultFunc = null // 返回函数
resultFunc = function () {
let currTime = Date.now(); // 获取当前时间时间戳
if (!prevTime) prevTime = currTime; // 第一次执行时prevTime赋值为当前时间
timer && clearTimeout(timer); // 每次都清除定时器,保证定时器只是在最后一次执行
if (currTime - prevTime > delay) { // 如果为true ,则表示两次执行函数的时间间隔为delay.
fn.apply(this, arguments);
prevTime = currTime;
clearTimeout(timer); // 清除定时器。用来处理假如函数停止调用时刚好函数也停止执行,不需要获取后续的值。 详见下面定时器的介绍。
}
// 当上面执行currTime - prevTime > delay 为false时,执行定时器。
// 用来处理:假如下次函数执行时间未到,函数不继续调用了,会造成最后一次函数执行 到 最后一次函数调用之间的值获取不到。
timer = setTimeout(function () {
prevTime = Date.now();
timer = null;
fn.apply(this, arguments);
}, delay);
}
resultFunc.cancel = function () {
clearTimeout(timer)
fn.apply(this, arguments);
prevTime = Date.now();
}
return resultFunc
}