继《Vue全局指令防止重复点击(等待请求)》之后,感觉指令方式还是不太友好,而且嵌套闭包比较麻烦,于是想到了Vue的全局混入,利用混入,给组件绑定click事件。
一、实现原理
与指令方式大致一样,只不过事件方式则是利用组件的事件监听属性完成绑定,这种方式更加友好、简洁、易懂。
二、使用
html
<el-button type="primary" icon="el-icon-search" size="mini" @conClick="handleQuery">搜索</el-button>
三、注意事项
1. 同步和异步回调
当前方式同样支持同步和异步回调,且异步回调需闭包
同步:
js
handleQuery() {
this.queryParams.pageNum = 1;
await this.getList();
}
异步回调:
js
handleQuery() {
return (removeDisabled) => {
// 去掉组件禁用
removeDisabled();
}
}
四、代码
js
import Vue from 'vue'
Vue.mixin({
mounted() {
// 获取组件所有的监听事件,判断有没有conClick
if (this.$listeners && this.$listeners.conClick && this.$listeners.conClick instanceof Function) {
// 如果有的话给对应的DOM添加click监听
const el = this.$el;
el.addEventListener('click', async (e) => {
// 自定义点击开始DOM状态
let hasCb = false;
el.classList.add('is-disabled');
el.disabled = true;
// 执行组件绑定的事件
const res = await this.$listeners.conClick();
if (res instanceof Function) {
// 如果获取的结果为方法,则为异步回调
hasCb = true;
const d = res(() => {
el.disabled = false;
el.classList.remove('is-disabled');
})
if (!(d instanceof Promise)) {
hasCb = true;
} else {
await d;
}
}
// 自定义点击结束DOM状态
if (!hasCb) {
el.disabled = false;
el.classList.remove('is-disabled');
}
});
}
}
})