需求说明
- 每次离开页面前,需要弹窗提示页面内容未保存

- 原始代码
javascript
复制代码
beforeRouteLeave(to, from, next) {
Dialog.confirm({
title: "标题",
message: "退出当前页将丢失未保存内容",
confirmButtonText: "留在当前",
cancelButtonText: "确定退出",
})
.then(() => {
next(false);
})
.catch(() => {
next();
});
},
发现问题
- 第一次离开页面时,触发路由守卫,confirm 生效弹出。
- confirm 选择"留在当前"时,即执行 next(false)
- 再次离开页面时,触发路由守卫,但是 confirm 并未弹出,当前页面闪动。
问题解决
- 只要进入路由守卫,优先拦截下来,然后再进行后续的操作,手动做一个延时
javascript
复制代码
beforeRouteLeave(to, from, next) {
next(false);
setTimeout(() => {
Dialog.confirm({
title: "标题",
message: "退出当前页将丢失未保存内容",
confirmButtonText: "留在当前",
cancelButtonText: "确定退出",
})
.then(() => {})
.catch(() => {
next();
});
}, 100);
},
完整案例
- 另外可添加一些变量,用于标识,当前页面是否编辑过,或者退出页面时是否需要拦截
html
复制代码
<template>
<div>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { Dialog } from "vant";
export default {
data() {
return {
form: {
name: "",
region: "",
},
lockFlag: false, // 锁 - 优先级最高的
};
},
computed: {
isEdit() {
// 当前页面是否编辑过?
let flag1 = this.form.name;
let flag2 = this.form.region;
return flag1 || flag2 ? true : false;
},
},
beforeRouteLeave(to, from, next) {
if (this.lockFlag) {
// 一些不需要判断编辑状态的场合
next();
} else if (this.isEdit) {
// 当前页面编辑过,先拦截住
next(false);
setTimeout(() => {
Dialog.confirm({
title: "标题",
message: "退出当前页将丢失未保存内容",
confirmButtonText: "留在当前",
cancelButtonText: "确定退出",
})
.then(() => {})
.catch(() => {
next();
});
}, 100);
} else {
// 在当前页没做操作,直接走了
next();
}
},
methods: {
onSubmit() {
// 走个提交接口
setTimeout(() => {
this.$message({
message: "保存成功",
type: "success",
});
this.lockFlag = true; // 如果是保存成功,退出当前页时,就不要再进行编辑与否的判断了
this.$router.back();
}, 100);
},
},
};
</script>