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模式并不会失效

相关推荐
知识分享小能手1 天前
uni-app 入门学习教程,从入门到精通,uni-app基础扩展 —— 详细知识点与案例(3)
vue.js·学习·ui·微信小程序·小程序·uni-app·编程
MC丶科1 天前
【SpringBoot 快速上手实战系列】5 分钟用 Spring Boot 搭建一个用户管理系统(含前后端分离)!新手也能一次跑通!
java·vue.js·spring boot·后端
90后的晨仔1 天前
Pinia 状态管理原理与实战全解析
前端·vue.js
90后的晨仔1 天前
Vue3 状态管理完全指南:从响应式 API 到 Pinia
前端·vue.js
90后的晨仔1 天前
Vue 内置组件全解析:提升开发效率的五大神器
前端·vue.js
我胡为喜呀1 天前
Vue3 中的 watch 和 watchEffect:如何优雅地监听数据变化
前端·javascript·vue.js
Sheldon一蓑烟雨任平生1 天前
Vue3 列表渲染
vue.js·vue3·v-for·列表渲染·vue3 列表渲染·v-for 循环对象·v-for与计算属性
鹿鹿鹿鹿isNotDefined1 天前
Pixelium Design:Vue3 的像素风 UI 组件库
前端·javascript·vue.js
武昌库里写JAVA1 天前
C语言 函数指针和指针函数区别 - C语言零基础入门教程
vue.js·spring boot·sql·layui·课程设计
Itai1 天前
自定义 markdown 解析规则并渲染 Vue 组件
vue.js