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 小时前
Vue入门-指令学习-v-html
vue.js·学习·html
无咎.lsy1 小时前
vue之vuex的使用及举例
前端·javascript·vue.js
工业互联网专业2 小时前
毕业设计选题:基于ssm+vue+uniapp的校园水电费管理小程序
vue.js·小程序·uni-app·毕业设计·ssm·源码·课程设计
计算机学姐2 小时前
基于SpringBoot+Vue的在线投票系统
java·vue.js·spring boot·后端·学习·intellij-idea·mybatis
twins35203 小时前
解决Vue应用中遇到路由刷新后出现 404 错误
前端·javascript·vue.js
qiyi.sky3 小时前
JavaWeb——Vue组件库Element(3/6):常见组件:Dialog对话框、Form表单(介绍、使用、实际效果)
前端·javascript·vue.js
杨荧4 小时前
【JAVA开源】基于Vue和SpringBoot的洗衣店订单管理系统
java·开发语言·vue.js·spring boot·spring cloud·开源
Front思4 小时前
vue使用高德地图
javascript·vue.js·ecmascript
花花鱼7 小时前
@antv/x6 导出图片下载,或者导出图片为base64由后端去处理。
vue.js
流烟默7 小时前
Vue中watch监听属性的一些应用总结
前端·javascript·vue.js·watch