Vant和ElementPlus在vue的hash模式的路由下路由离开拦截使用Dialog和MessageBox失效

问题复现

ElementPlus:当点击返回或者地址栏回退时,MessageBox无效

html 复制代码
<template>
  <div>Element Plus Dialog 路由离开拦截测试</div>
  <el-button type="primary" @click="$router.back()">返回</el-button>
</template>

<script setup lang="ts">
import { onBeforeRouteLeave } from 'vue-router';
import { ElMessageBox } from 'element-plus'

/** 路由拦截 */
onBeforeRouteLeave(async (to, from, next) => {
  try {
    await ElMessageBox.confirm(
    '确定要离开吗',
    {
      cancelButtonText:'取消',
      confirmButtonText:'确定',
      type: 'warning',
    }
  )
    next();
  } catch (error) {
    next(false);
  }
});
</script>

Vant:当点击返回或者地址栏回退时,Dialog第一次生效,第二次开始无法生效

html 复制代码
<template>
  <div>Vant Plus Dialog 路由离开拦截测试</div>
  <van-button type="primary" @click="$router.back()">返回</van-button>
</template>

<script setup lang="ts">
import { onBeforeRouteLeave } from "vue-router";
import { Dialog,Toast } from "vant";

/** 路由拦截 */
onBeforeRouteLeave(async (to, from, next) => {  
  try {
    await Dialog.confirm({
      message: "确定要离开吗",
      confirmButtonColor: "#357ef7",
    });
    next();
  } catch (error) {
    next(false);
  }
});
</script>

失效原因

Vant和ElementPlus的Dialog都有一个当路由地址变化时自动关闭的默认属性(官方文档中有说明)(ElementPlus是当hash变化的时候自动关闭),所以导致我们希望的是Dialog在路由变化的时候生效,但是Dialog在路由地址变化的时候自动小时了,产生了矛盾,所以失效

Vant

ElementPlus

Vant之所以第一次会生效,因为Vant在第一次的时候并未挂载到DOM节点中,导致默认的路由变化关闭Dialog不起作用,但是第二次开始Dialog已经挂载到DOM节点上了,默认路由关闭的属性也就生效了(Vant的Dialog第一次挂载之后不会移除,会通过display属性控制显示隐藏,ElementPlus的MessageBox会动态的挂载和移除,上述GIF的DOM中可以看出二者的差别)

解决方法

方案一:使用history模式

js 复制代码
import {
  createRouter,
  createWebHistory,
  createWebHashHistory,
  RouteRecordRaw,
} from "vue-router";

const router = createRouter({
  history: createWebHistory(),
  // history: createWebHashHistory(),
  routes,
});

方案二:关闭对应的路由变化自动关闭的属性

ElementPlus

js 复制代码
/** 路由拦截 */
onBeforeRouteLeave(async (to, from, next) => {
  try {
    await ElMessageBox.confirm(
    '确定要离开吗',
    {
      cancelButtonText:'取消',
      confirmButtonText:'确定',
      type: 'warning',
      // 禁用路由变化自动关闭
      closeOnHashChange:false
    }
  )
    next();
  } catch (error) {
    next(false);
  }
});

Vant

js 复制代码
/** 路由拦截 */
onBeforeRouteLeave(async (to, from, next) => {  
  try {
    await Dialog.confirm({
      message: "确定要离开吗",
      confirmButtonColor: "#357ef7",
      // 禁用路由变化自动关闭
      closeOnPopstate: false,
    });
    next();
  } catch (error) {
    next(false);
  }
});

注意

上述的时效问题仅在hash模式的路由且并未关闭默认的路由变化自动关闭的属性时生效,history模式并不会失效

相关推荐
爱泡脚的鸡腿2 分钟前
uni-app D6 实战(小兔鲜)
前端·vue.js
北极糊的狐13 分钟前
Vue3 中父子组件传参是组件通信的核心场景,需遵循「父传子靠 Props,子传父靠自定义事件」的原则,以下是资料总结
前端·javascript·vue.js
看到我请叫我铁锤1 小时前
vue3中THINGJS初始化步骤
前端·javascript·vue.js·3d
谢尔登1 小时前
defineProperty如何弥补数组响应式不足的缺陷
前端·javascript·vue.js
涔溪2 小时前
实现将 Vue2 子应用通过无界(Wujie)微前端框架接入到 Vue3 主应用中(即 Vue3 主应用集成 Vue2 子应用)
vue.js·微前端·wujie
T***u3333 小时前
前端框架在性能优化中的实践
javascript·vue.js·前端框架
jingling5554 小时前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js
油丶酸萝卜别吃4 小时前
Vue3 中如何在 setup 语法糖下,通过 Layer 弹窗组件弹出自定义 Vue 组件?
前端·vue.js·arcgis
J***Q29211 小时前
Vue数据可视化
前端·vue.js·信息可视化
JIngJaneIL12 小时前
社区互助|社区交易|基于springboot+vue的社区互助交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·社区互助