https://www.jianshu.com/p/c8b86b09daf0
1.节流、防抖、重绘、回流
函数节流: 指定时间间隔内只会执行一次任务;
函数防抖: 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。
①节流
stopClickLogin:false,
aaa(){
let that=this
if(that.stopClickLogin){
console.log(`请等待1s后再次点击 >>>>>>>>>`)
return false
}
that.stopClickLogin=true
setTimeout(()=>{
that.stopClickLogin=false
},5000)
console.log(`do something >>>>>>>>>`)
},
函数封装
公共函数设置
stopClick(name=`stopClick`,time=1000,msg=`请等待1s后再次点击`){
return new Promise((resolve,reject)=>{
if(that[name]){
console.log(`${msg} >>>>>>>>>`)
return false
}
that[name]=true
setTimeout(()=>{
that[name]=false
},time)
resolve()
})
}
引用节流函数
test(){
let that=this
that.stopClick(`stopClickLogin`).then(()=>{
console.log(`do something >>>>>>>>>`)
})
}
②防抖
③封装节流和防抖
1.vue 封装utils.js
/**
* @param {function} func 执行函数
* @param {number} time 防抖节流时间
* @param {boolean} isDebounce [1,3]为防抖组件,[2]为节流组件
* @param {this} ctx this 的指向
*/
const debounce = (func, time, isDebounce, ctx) => {
var timer, lastCall, rtn;
// 防抖函数
if (isDebounce == 1) {
rtn = (...params) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(ctx, params);
}, time);
};
} else if(isDebounce == 2){ // 节流函数
rtn = (...params) => {
const now = new Date().getTime();
if (now - lastCall < time && lastCall) return;
lastCall = now;
func.apply(ctx, params);
};
} else if(isDebounce == 3){ // 立即执行的防抖函数
rtn = (...params) => {
if (timer) clearTimeout(timer);
let callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, time)
if (callNow) func.apply(ctx, params)
};
}
return rtn;
};
export default {
name: 'Debounce',
abstract: true,
props: {
time: {
type: Number,
default: 800,
},
events: {
type: String,
default: 'click',
},
isDebounce: {
type: Number,
default: 1,
},
},
created() {
this.eventKeys = this.events.split(','); // 分隔事件
this.originMap = {}; // 储存事件,用于重新render时与子事件的对比
this.debouncedMap = {}; // 储存防抖节流事件
},
render() {
const vnode = this.$slots.default[0];
this.eventKeys.forEach(key => {
const target = vnode.data.on[key];
if (target === this.originMap[key] && this.debouncedMap[key]) {
vnode.data.on[key] = this.debouncedMap[key];
} else if (target) {
this.originMap[key] = target;
this.debouncedMap[key] = debounce(
target,
this.time,
this.isDebounce,
vnode
);
vnode.data.on[key] = this.debouncedMap[key]; // 重写子组件的事件
}
});
return vnode;
},
};
2.在main.js入口文件里面全局注册
1 // 防抖节流
2 import Debounce from './assets/componentFn/utils'
3 Vue.component('Debounce',Debounce)
3.使用方法
当是isDebounce= =1时表示是防抖函数,isDebounce= =2是节流函数,isDebounce==3是立即执行版防抖函数,time是执行时间间隔,UI框架click事件失效时可用修饰符native
<Debounce :time='1000' :isDebounce="3">
<Button type="warning" @click.native='btn'>btn</Button>
</Debounce>