bug 记录 - 路由守卫 beforeRouteLeave 与 confirm 结合,不生效问题

需求说明

  • 每次离开页面前,需要弹窗提示页面内容未保存
  • 原始代码
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>
相关推荐
丷丩1 小时前
MapLibre GL JS第27课:添加COG栅格源
javascript·map·mapbox·maplibre gl js
不好听6133 小时前
JavaScript 到底是怎么运行的?从编译阶段到执行上下文全面解析
javascript
丷丩3 小时前
MapLibre GL JS第29课:添加Canvas源
javascript·gis·map·mapbox·maplibre gl js
utf8mb4安全女神3 小时前
【rsyslog服务】把所有服务的“临界点”以上的错误都保存在/var/log/alert.log⽇志中
java·前端·javascript
csdn_aspnet3 小时前
javascript 算法 LeetCode 编号 70 - 爬楼梯
开发语言·javascript·算法·leetcode·ecmascript
swipe3 小时前
DeepAgents 多 Agent 深度调研助手工程实战:从 createDeepAgent 到可控调研工作流
javascript·面试·langchain
moMo4 小时前
JavaScript 变量提升,执行上下文里的各种门道
javascript·面试
weixin_471383034 小时前
由浅入深递归练习
前端·javascript·vue.js
丷丩4 小时前
MapLibre GL JS第21课:绘制GeoJSON点图标、注记
前端·javascript·gis·mapbox·maplibre gl js
丷丩5 小时前
MapLibre GL JS第20课:更新GeoJSON多边形
前端·javascript·gis·mapbox·maplibre gl js