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

相关推荐
SuperEugene16 小时前
表单最佳实践:从 v-model 到自定义表单组件(含校验)
前端·javascript·vue.js
我叫黑大帅1 天前
Vue3和Uniapp的爱恨情仇:小白也能懂的跨端秘籍
前端·javascript·vue.js
洋洋技术笔记1 天前
Vue实例与数据绑定
前端·vue.js
牛奶1 天前
Vue 基础理论 & API 使用
前端·vue.js·面试
牛奶1 天前
Vue 底层原理 & 新特性
前端·vue.js·面试
pe7er1 天前
状态提升:前端开发中的状态管理的设计思想
前端·vue.js·react.js
_AaronWong2 天前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
wuhen_n2 天前
双端 Diff 算法详解
前端·javascript·vue.js
爱勇宝2 天前
别再混用了!import.meta.env 与 process.env 的本质差异一次讲透
前端·javascript·vue.js
从文处安3 天前
「九九八十一难」组合式函数到底有什么用?
前端·vue.js