防抖
点击button按钮,设置定时器,在规定的时间内再次点击会重置定时器重新计时,在规定的时间没有再次点击才执行相关函数。
规定时间内最后一次点击有效。
节流
点击button按钮,执行相关函数。设置定时器,在规定的时间内连续点击均无效,定时器过后,可以再次点击。
规定时间内可点击一次(第一次点击有效)。
全局引入
新建js文件
在项目中新建 myDirective.js 文件。通过export default暴露出来。
/*
* @Description: 添加全局自定义指令。
* 防抖,v-debounce。节流,v-throttle、v-throttle-disabled(可能无效)。
* 示例:<el-button v-throttle="[resetData]">刷新</el-button>,使用默认配置,监听click事件,300毫秒内只会执行一次函数resetData
* 传递参数:<el-button v-throttle="[()=>resetData(param)]">刷新</el-button>
*/
export default {
install(Vue, Options) {
/*
* 防抖,规定时间内(默认300毫秒)最后一次点击有效。
* @param {?Number|300} time - 间隔时间,毫秒
* @param {Function} fn - 执行函数
* @param {?String|"click"} event - 事件类型 例:"click"
* @param {Array} binding.value - [fn,event,time]
* 例:<el-button v-debounce="[resetData,`click`,300]">刷新</el-button>
* 也可简写成:<el-button v-debounce="[resetData]">刷新</el-button>
*/
// 注册一个全局自定义指令 `v-debounce`
Vue.directive('debounce', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function(el, binding) {
//binding.value,使用自定义指令v-debounce时填写的参数
//解构赋值,定义了3个变量,将参数(数组)按顺序进行赋值
let [fn, event = "click", time = 300] = binding.value
let timer
el.addEventListener(event, () => {
//默认监听的事件为click
//判断计时器是否存在,存在则清除计时器。重新创建计时器,到时间后执行函数fn
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => fn(), time)
})
}
})
/*
* 节流,规定时间内可点击一次(第一次点击有效)。
* @param {?Number|300} time - 间隔时间,毫秒
* @param {Function} fn - 执行函数
* @param {?String|"click"} event - 事件类型 例:"click"
* @param {Array} binding.value - [fn,event,time]
* 例:<el-button v-throttle="[resetData,`click`,300]">刷新</el-button>
* 传递参数则:<el-button v-throttle="[()=>resetData(param),`click`,300]">刷新</el-button>
*/
// 注册一个全局自定义指令 `v-throttle`
Vue.directive('throttle', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function(el, binding) {
//binding.value,使用自定义指令v-throttle时填写的参数
//解构赋值,定义了3个变量,将参数(数组)按顺序进行赋值
let [fn, event = "click", time = 300] = binding.value
let timer = null;
el.addEventListener(event, () => {
//默认监听的事件为click
//判断计时器是否存在,不存在则执行函数fn,创建计时器
if (timer == null) {
fn();
timer = setTimeout(() => timer = null, time)
}
})
}
})
/*
* 节流方案二,通过禁用html标签,规定时间内可点击一次(第一次点击有效)。
* 应用在封装的组件中可能无效。
* @param {?String|"click"} event - 事件类型 例:"click"
* @param {?Number|2000} time - 间隔时间,毫秒
* @param {Array} binding.value - [event,time]
* 例:<button v-throttle-disabled="[]">测试按钮</button>
*/
//注册一个全局自定义指令 `v-throttle-disabled`
Vue.directive('throttle-disabled', {
// 当被绑定的元素插入到 DOM 中时……
inserted(el, binding) {
let [event = "click", time = 2 * 1000] = binding.value
el.addEventListener(event, () => {
//默认监听click事件
//当 dom元素el 非禁用状态时 将其设置为禁用状态,同时设置计时器,规定时间后(默认2秒)启用。
if (!el.disabled) {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, time)
}
})
}
})
}
}
配置main.js文件
在入口文件main.js引入
//引入自定义指令,方便全局使用
import myDirective from '@/utils/myDirective.js';
Vue.use(myDirective);
使用示例
<button v-debounce="[debounceTest,`click`,3000]">防抖(延迟3000毫秒执行)</button>
<button v-throttle="[debounceTest,`click`,3000]">节流(3000毫秒内只执行1次)</button>