Vue-防止重复点击指令
背景
在日常业务开发中,经常会需要处理按钮防止重复点击事件,因为在提交订单和支付金额的场景需要只触发一次,多次触发会导致业务异常
Vue局限
vue的事件响应是通过事件队列实现的,在极限情况(快速点击)是没办法防止按钮多次触发,即使使用了$nextTick,也只是延迟触发,没办法保证按钮不会重复触发
解决方案
我通过闭包创建一个状态机,实时管理状态变化,减少中间环节,从而实现数据快速响应
// 状态机,用于简单判断状态,用于防止按钮极限快速点击
je.status = (function () {
let loading = false;
function lock() {
loading = true;
}
function unlock() {
loading = false
}
function getStatus() {
return loading;
}
return {
lock,
unlock,
getStatus
}
})()
通过立即执行函数,把一部分状态存储在内存
指令
Vue.directive('singleClick', function (el, binding) {
el.onclick = function (event) {
if (el.disabled) return;
if (je.status.getStatus() === true) {
return;
}
je.status.lock();
binding.value();
}
})
如何使用
提交发布
commitData() {
this.$refs.telexForm.verify((val) => {
if (val) {
this.$api.post('/post/v1/post', this.form).then((res) => {
this.$Message.success('提交成功!')
this.$router.push({
path: '/content/list',
})
je.status.unlock()
})
} else {
this.$Message.error('必填项不能为空!')
je.status.unlock()
}
})
}
重点
由于一般提交数据都是异步,前端没办法预估事件什么时候结束,所以需要在接口请求完数据,再改变状态
优点
通过指令的方式,和@click一致,把复杂逻辑封装在指令中,可以减少学习成本,无缝切换。