Vue3-39-路由-导航异常的检测 afterEatch 与 编程式导航之后的订阅动作

说明

本文主要是介绍一下 路由的后置守卫 afterEatch 的一个重要的作用 : 就是检测路由异常信息。
它的实现方式是 通过第三个参数来返回的。
而且,它的异常检测是全局的。

导航的异常有以下三种类型:
aborted : 在导航守卫中 被拦截并返回了false;
cancelled : 在导航完成之前又产生了一次新的导航;
duplicated : 导航被阻止,已经在目标位置了。
下面通过案例来认识一下这三种异常。

补充1

vue-router 中提供了 关于路由导航异常的检测API
isNavigationFailure() : 判断路由是否是某种异常
NavigationFailureType : 包含了上述三种异常状态的枚举。

补充2

我们在代码中通过 编程式导航push 方法进行路由时,
都会返回一个 Promise对象,
我们可以正常的订阅这个 Promise 对象,从而实现 在路由结束之后做一些逻辑处理。

aborted

在导航守卫中 被拦截并返回了false。
(1)在前置守卫中拦截 /b;
(2)在后置守卫中检测到 aborted 异常信息。

路由配置如下

// 导入 定义路由的两个方法
import {
   createRouter,createWebHistory}  from 'vue-router'

// 懒加载写法: 先声明,下面直接使用
const componentA = () => import('./componentA.vue')
const componentB = () => import('./componentB.vue')

// 声明路由跳转的路径与组件的对应关系
const routsList = [
    // 直接使用上面声明的组件
    {
   path:'/a',name:'aroute',component:componentA},
    {
   path:'/b',name:'broute',component:componentB}
]

// 创建路由的实例对象
const routerConfigObj = createRouter({
   
    history:createWebHistory('abc'), // 带一个参数,表示是路由的一个前缀
    routes:routsList // 指定路由的配置列表
})


// 前置守卫
routerConfigObj.beforeEach((to,from)=>{
   
    console.log('前置守卫 : to  : ',to)
    console.log('前置守卫 :from : ',from)
    

    // 当路由地址是 /b 时 , 手动停止跳转,模拟跳转中止的情况
    if(to.path == '/b'){
   
        console.log('前置守卫 : 是 /b 路由,拦截它')
        console.log('------')
        // 直接返回 false 
        return false; // aborted

    }
    return true
})


// 后置守卫
routerConfigObj.afterEach((to,from,failureObj) => {
   
    console.log('后置守卫 : to  : ',to)
    console.log('后置守卫 :from : ',from)
    console.log('后置守卫 :failureObj : ',failureObj)
    console.log('------')
})


// 导出路由的对象
export default routerConfigObj;

运行结果:

在这里插入图片描述

cancelled

在导航守卫中 被拦截 并且 重新导航到一个新的路由上去。

路由配置如下:

// 导入 定义路由的两个方法
import {
   createRouter,createWebHistory}  from 'vue-router'

// 懒加载写法 : 先声明,下面直接使用
const componentA = () => import('./componentA.vue')
const componentB = () => import('./componentB.vue')

// 声明路由跳转的路径与组件的对应关系
const routsList = [
    // 直接使用上面声明的组件
    {
   path:'/a',name:'aroute',component:componentA},
    {
   path:'/b',name:'broute',component:componentB}
]

// 创建路由的实例对象
const routerConfigObj = createRouter({
   
    history:createWebHistory('abc'), // 带一个参数,表示是路由的一个前缀
    routes:routsList // 指定路由的配置列表
})


// 前置守卫
routerConfigObj.beforeEach((to,from)=>{
   
    console.log('前置守卫 : to  : ',to)
    console.log('前置守卫 :from : ',from)
    

    // 当路由地址是 /b 时 , 手动停止跳转,模拟跳转中止的情况
    if(to.path == '/b'){
   
        console.log('前置守卫 : 是 /b 路由,拦截它,重新push到 /a 这个路由上去')
        console.log('------')
        // push 到新的路由中去
        routerConfigObj.push('/a') // cancelled

    }
    
    return true
})

// 后置守卫
routerConfigObj.afterEach((to,from,failureObj) => {
   
    console.log('后置守卫 : to  : ',to)
    console.log('后置守卫 :from : ',from)
    console.log('后置守卫 :failureObj : ',failureObj)
    console.log('------')
})


// 导出路由的对象
export default routerConfigObj;

运行结果

在这里插入图片描述

duplicated

路由重复跳转时会触发的异常。
例如 : 当前我们已经在 /a 上面了,点击按钮,又想跳转到 /a 上面,此时就会触发这个异常。

本案例就使用到了 补充1补充2 中的知识点了。

路由配置

// 导入 定义路由的两个方法
import {
   createRouter,createWebHistory}  from 'vue-router'

// 懒加载写法 : 先声明,下面直接使用
const componentA = () => import('./componentA.vue')

// 声明路由跳转的路径与组件的对应关系
const routsList = [
    // 直接使用上面声明的组件
    {
   path:'/a',name:'aroute',component:componentA}
]

// 创建路由的实例对象
const routerConfigObj = createRouter({
   
    history:createWebHistory('abc'), // 带一个参数,表示是路由的一个前缀
    routes:routsList // 指定路由的配置列表
})


// 前置守卫
routerConfigObj.beforeEach((to,from)=>{
   
    console.log('前置守卫 : to  : ',to)
    console.log('前置守卫 :from : ',from)
    console.log('------')
})

// 后置守卫
routerConfigObj.afterEach((to,from,failureObj) => {
   
    console.log('后置守卫 : to  : ',to)
    console.log('后置守卫 :from : ',from)
    console.log('后置守卫 :failureObj : ',failureObj)
    console.log('------')
})

// 导出路由的对象
export default routerConfigObj;

组件A 中的操作 : 有一个按钮,点击按钮,仍然跳转到当前的路由上

<template>
    <div class="diva">
        这是组件A
        <br>
        <button @click="goToA">跳转到组件A</button>
    </div>
    
</template>

<script setup lang="ts">

    // 引入两个路由相关的方法
    import {
      useRouter,useRoute} from 'vue-router';

    // 声明 路由实例对象 和 当前路由对象
    const routerObj = useRouter()
    const currentRoute = useRoute()

    // 打印一下路由实例对象 和 当前路由对象
    console.log('A 组件 中 路由实例对象 :',routerObj)
    console.log('A 组件 中 当前路由对象 :',currentRoute)

	// 导入 路由异常 相关的API 
    import {
      isNavigationFailure,NavigationFailureType} from 'vue-router';

    // 跳转到自己
    const goToA = () =>{
     
        routerObj.push('/a')
        .then((failure:any) => {
     
            console.log('push 中的错误返回结果 :', failure)
            if(isNavigationFailure(failure,NavigationFailureType.duplicated)){
     
                console.log('路由重复了')
            }else{
     
                console.log('路由没有重复')
            }
        })
    }

</script>

<style scoped>
    .diva{
     
        width: 300px;
        height: 200px;
        background: red;
    }
</style>

运行结果

在这里插入图片描述

相关推荐

  1. Vue3程式导航

    2024-01-07 19:12:02       50 阅读
  2. React Router 6 重定向程式导航指南

    2024-01-07 19:12:02       33 阅读
  3. vue3导航故障

    2024-01-07 19:12:02       39 阅读
  4. VueRouter程式导航导航守卫

    2024-01-07 19:12:02       53 阅读
  5. vue3之声明式和程式导航

    2024-01-07 19:12:02       44 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-07 19:12:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-07 19:12:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-07 19:12:02       82 阅读
  4. Python语言-面向对象

    2024-01-07 19:12:02       91 阅读

热门阅读

  1. kafka 偏移量的类型与提交方式

    2024-01-07 19:12:02       67 阅读
  2. 华为OD机试 2024 真题 - VLAN资源池 c++实现

    2024-01-07 19:12:02       57 阅读
  3. 【我的Rust库】get_local_info 0.1.6发布

    2024-01-07 19:12:02       50 阅读
  4. C#-接口

    2024-01-07 19:12:02       52 阅读
  5. 解释 Git 的基本概念和使用方式。

    2024-01-07 19:12:02       45 阅读
  6. 自用PHP在线Access转html表格小功能(快速预览access)

    2024-01-07 19:12:02       56 阅读