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 4 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>
4.參考網址:
