在Web应用中,当用户快速多次点击按钮或触发异步操作时,可能会导致:
在所有触发后台操作的前端事件中添加进度条和防重复点击机制。
在按钮上绑定loading属性,在请求期间禁用按钮并显示加载状态。
<template>
<el-button
:loading="loading"
@click="handleAction"
:disabled="loading">
{{ loading ? '处理中...' : '提交' }}
</el-button>
</template>
<script>
export default {
data() {
return {
loading: false
}
},
methods: {
async handleAction() {
if (this.loading) return; // 防止重复点击
this.loading = true;
try {
// 执行后台操作
await this.apiCall();
} finally {
this.loading = false; // 确保无论成功失败都恢复状态
}
}
}
}
</script>
对于页面级别的操作,可以使用全局Loading遮罩:
methods: {
async handleAction() {
const loadingInstance = this.$loading({
lock: true,
text: '处理中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
try {
await this.apiCall();
} finally {
loadingInstance.close();
}
}
}
对于搜索框等频繁触发的操作,可以使用防抖或节流:
import { debounce } from 'lodash';
export default {
methods: {
// 防抖:延迟执行,适用于搜索
search: debounce(function(query) {
this.performSearch(query);
}, 300),
// 节流:固定频率执行,适用于滚动等
throttleClick: throttle(function() {
this.handleScroll();
}, 1000)
}
}
创建可复用的防重复点击组件:
<!-- ReusableButton.vue -->
<template>
<el-button
v-bind="$attrs"
:loading="isLoading"
@click="handleClick"
:disabled="isLoading || disabled">
<slot></slot>
</el-button>
</template>
<script>
export default {
name: 'ReusableButton',
props: {
disabled: Boolean,
apiFunction: Function,
autoReset: {
type: Boolean,
default: true
}
},
data() {
return {
isLoading: false
}
},
methods: {
async handleClick(event) {
if (this.isLoading || this.disabled) return;
this.isLoading = true;
try {
await this.apiFunction();
} finally {
if (this.autoReset) {
this.isLoading = false;
}
}
}
}
}
</script>
<template>
<el-form :model="form" ref="formRef">
<!-- 表单内容 -->
<el-form-item>
<el-button
type="primary"
:loading="submitting"
@click="submitForm">
{{ submitting ? '提交中...' : '提交' }}
</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
submitting: false,
form: {}
}
},
methods: {
async submitForm() {
if (this.submitting) return; // 防重复提交
this.submitting = true;
try {
await this.$refs.formRef.validate();
await this.submitToBackend(this.form);
this.$message.success('提交成功');
} catch (error) {
this.$message.error('提交失败');
} finally {
this.submitting = false;
}
}
}
}
</script>
以下操作都应该添加防重复点击机制: