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