继《Vue全局指令防止重复点击(等待请求)》之后,感觉指令方式还是不太友好,而且嵌套闭包比较麻烦,于是想到了Vue的全局混入,利用混入,给组件绑定click事件。
一、实现原理
与指令方式大致一样,只不过事件方式则是利用组件的事件监听属性完成绑定,这种方式更加友好、简洁、易懂。
二、使用
<el-button type="primary" icon="el-icon-search" size="mini" @conClick="handleQuery">搜索</el-button>
三、注意事项
1. 同步和异步回调
当前方式同样支持同步和异步回调,且异步回调需闭包
同步:
handleQuery() {this.queryParams.pageNum = 1;await this.getList();
}
异步回调:
handleQuery() {return (removeDisabled) => {// 去掉组件禁用removeDisabled();}
}
四、代码
import Vue from 'vue'Vue.mixin({mounted() {// 获取组件所有的监听事件,判断有没有conClickif (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');}});}}
})