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;

运行结果:

Vue3-39-路由-导航异常的检测 afterEatch 与 编程式导航之后的订阅动作_第1张图片

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;

运行结果

Vue3-39-路由-导航异常的检测 afterEatch 与 编程式导航之后的订阅动作_第2张图片

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">跳转到组件Abutton>
    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>

运行结果

Vue3-39-路由-导航异常的检测 afterEatch 与 编程式导航之后的订阅动作_第3张图片

你可能感兴趣的:(Vue3,vue3,路由,路由导航异常,导航异常检测,编程式导航异常检测)