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>
相关推荐
夏殇之殁3 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
新中地GIS开发老师4 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
丙氨酸長鏈5 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen6 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
许彰午8 小时前
政务督办的分合模式:主办协办的并发审批
前端·javascript·政务
易筋紫容8 小时前
创建型模式:对象的诞生艺术
开发语言·前端·javascript
0_Error_10 小时前
猫国建设者 修改资源 自动采集
javascript
贩卖黄昏的熊10 小时前
NestJS简明教程——安全
开发语言·javascript·安全·typescript·nest.js
贩卖黄昏的熊10 小时前
NestJS简明教程——异常处理和日志
javascript·node.js·nest.js
海带紫菜菠萝汤14 小时前
FFmpeg.wasm 实践:在浏览器中运行 FFmpeg 的能力边界与性能瓶颈
前端·javascript·ffmpeg·音视频·wasm