经常会遇到的一个问题(如图所示),在短时间内点击按钮多次,会造成重复提交,出现多条数据,以下讲一下我的解决办法,比较类似,但是用起来能有效阻止提交多次。
使用Vue.directive()来自定义全局注册指令,在main.js中加入下方这段代码,可以全局应用。
// 防止el-button重复点击
Vue.directive('preventReClick', {
inserted(el, binding) {
el.addEventListener('click', () => {
if (!el.disabled) {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, binding.value || 2000)
}
})
}
});
接着在el-button中添加v-preventReClick,就可实现效果,在点击之后按钮变为禁用状态,持续禁用两秒,两秒之后便可再一次提交
// 添加新属性
<el-button type="primary" @click="handleSave" v-preventReClick>保存</el-button>
划重点:然而,经测试表明,只针对el-button生效, 针对普通的div或者自行封装的组件并没有效果,因为disabled正常情况下,不会阻止@click的点击效果
为此,进行如下改进:
//改进方法一:
import Vue from 'vue'
const preventReClick = Vue.directive('preventReClick', {
inserted: function(el, binding) {
el.addEventListener('click', (e) => {
if (!el.disabled) {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, binding.value || 1000)
} else {
// disabled为true时,阻止默认的@click事件
e.preventDefault()
e.stopPropagation()
}
}, true)
}
});
export { preventReClick }
//改进方法二:
import Vue from 'vue'
const preventReClick = Vue.directive('preventReClick', {
inserted: function(el, binding) {
el.addEventListener('click', (e) => {
if (!el.disabled) {
el.style.pointerEvents = 'none'
setTimeout(() => {
el.style.pointerEvents = 'auto'
}, binding.value || 2000)
} else {
// disabled为true时,阻止默认的@click事件
e.preventDefault()
e.stopPropagation()
}
}, true)
}
});
export { preventReClick }
index.vue
<div @click='handleClick' v-preventReClick='1000'>测试重复点击</div>
在export default {} 中写入下面这段代码,进行局部注册指令
// 防止el-button重复点击
directives: {
preventReClick: {
// 指令的定义
inserted(el, binding) {
el.addEventListener('click', () => {
if (!el.disabled) {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, binding.value || 2000)
}
})
}
}
},
接着也是在el-button中添加v-preventReClick,就可实现效果
// 添加新属性
<el-button type="primary" @click="handleSave" v-preventReClick>保存</el-button>
在el-button中添加disabled属性,进行动态控制
// 添加属性
<el-button type="primary" @click="handleSave" :disabled="disabled">保存</el-button>
在需要调用的事件中,控制按钮启用禁用,实现的效果是在点击按钮后禁用两秒,两秒之后,按钮恢复启用状态
// 调用事件动态控制disabled属性
handleSave() {
this.disabled = true;
let params = {
data: this.data,
};
this.$requestFn("POST", this.$url.export.test, params)
.then((res) => {
this.$toast.success("保存成功");
})
.finally(() => {
setTimeout(() => {
this.disabled = false;
}, 2000)
});
},
以上是三种不同的方法,都能实现防止按钮重复点击导致提交多次的问题。