方法一、封装
vue 防抖节流函数——组件封装
防抖(debounce)
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
节流(throttle)
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
就相当于,一个水龙头在滴水,可能一次性会滴很多滴,但是我们只希望它每隔 500ms 滴一滴水,保持这个频率。即我们希望函数在以一个可以接受的频率重复调用。
vue 封装utils.js
复制代码
const debounce = (func, time, isDebounce, ctx) => {
var timer, lastCall, rtn;
//防抖函数
if (isDebounce) {
rtn = (...params) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(ctx, params);
}, time);
};
} else {//节流函数
rtn = (...params) => {
const now = new Date().getTime();
if (now - lastCall < time && lastCall) return;
lastCall = now;
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: Boolean,
default: false,
},
},
created() {
this.eventKeys = this.events.split(',');
this.originMap = {};
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;
},
};
复制代码
然后我们在main.js入口文件里面全局注册一下
import Debounce from '@/config/debounce'
Vue.component('Debounce',Debounce)
使用方法
<Debounce :time='1000' isDebounce>
<button @click='btn'>btn</button>
</Debounce>
注:若报错clickundefined——一般是使用elbtn的时候,需要在el-btn外加一层span标签,将click事件写在span下面
二、自定义指令
main.js下面加入以下代码
Vue.use(ElementUI);
Vue.directive('noMoreClick', {
inserted(el, binding) {
el.addEventListener('click', e => {
el.classList.add('is-disabled');
el.disabled = true;
setTimeout(() => {
el.disabled = false;
el.classList.remove('is-disabled');
}, 3000)
})
}
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
在使用时,加入v-no-more-click即可
<el-button type="danger" @click="sureCancelDialog" v-no-more-click>删 除</el-button>