Vue Router 进阶

 Vue Router 通过跳转或取消的方式守卫导航,可以在导航解析的不同节点来控制路由的跳转与取消。定义路由时,可以配置元信息。可以定制页面跳转的过度效果。还可以在程序已经运行的时候添加和删除路由。

1 Router进阶

1.1 导航守卫

守卫,是指通过某种方式来控制路由的跳转与取消。可以全局的、单个路由独享的,或者组件级的方式来提供守卫。

图 完整的导航解析流程。

从beforeRouteLeave 到 beforeResolve,都可以控制路由的跳转与取消。

导航结果

返回值

正常导航

返回undefined、true或没有返回

跳转到其他路由

 返回路径的字符串,或者一个对象(包含name字段,用来指示路由)。

停留在当前路由

返回false。

表 守卫的返回值与控制路由的跳转

// 守卫的不同返回值
router.beforeEach((to,from) => {
    const name = to.name 
    if (name === 'detail') {
        return false; // 将不会跳转
    }
    if (name === 'other1') {
        return '/other' // 跳转到这个路由
    }
    if (name === 'other2) {
        return {name: 'user'} // 跳转到名为user的路由
    }
    // 正常跳转到目标路由,等效于 return true 或 return undefined
})
// 在定义路由时,为专属路由定义beforeEnter守卫
{
    path: 'order/:id', 
    name: 'userOrder',
    component: () => import("@/views/UserOrder.vue"),
    beforeEnter: (to,from) => {
       console.log('userOrder route,beforeEnter',to,from)
    }
}
// 在组合式Api中,定义beforeRouteLeave、beforeRouteUpdate 守卫
<script setup>
    import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
    onBeforeRouteLeave((to,from) => {
    
    })
</script>

1.2 动态路由

在程序已经运行时可以添加或删除路由,主要是通过router.addRoute() 和 router.removeRoute()这两个函数来实现。

// 在守卫中动态添加路由
router.beforeEach((to,from) => {
    if (to.name === 'goodsDetail' && !router.hasRoute('goodsDetail')) {
        // 这里添加的时一个嵌套路由,如果不是嵌套路由,则把第一个参数删除
        router.addRoute('goodsList',{name: 'goodsDetail',path: 'detail', component: () => import('@/views/GoodsDetail.vue')}) 
        return to.fullPath // 添加完路由后,它仍不会导航到目标路由,需要手动return 一下
    }
})

当路由被删除时,所有的别名和子路由也会被同时删除。删除路由的不同方法:

  1. 调用router.removeRoute()方法,参数是需要被删除路由的名称。
  2. 通过调用reouter.addRoute()返回的回调:
  3. 添加一个名称冲突的路由,如果添加与现有途径名称相同的路由,会先删除这个路由,再添加新的路由。
const removeRoute = router.addRoute(路由)

removeRoute();// 会删除这个路由

1.3 导航故障

如果导航被阻止,导致用户停留在同一个页面上,由router.push返回的Promise解析值将是Navigation Failure。 否则返回值为undefined。

isNavigationFailure 用来检测这个错误类型。

const result = await router.push(‘/other’)

if (isNavigationFailure (result,NavigationFailureType.aborted)) {}

枚举值

错误情况

aborted

在导航守卫中返回false,中断了本次导航。

cancelled

在当前导航完成之前又有了一个新的导航。

duplicated

目标位置是当前位置

表 NavigationFailureType 的枚举值对应的错误情况

1.4 扩展RouterLink

通过自定义一个RouterLink,来满足某些业务场景。

<script lang="ts" setup>
import {computed, defineProps} from "vue";
    import {RouterLink} from "vue-router";

    const props = defineProps({
      ...RouterLink.props,
      inactiveClass: String
    })

    const isExternalLink = computed(() => {
      return typeof props.to === 'string' && props.to.startsWith('http')
    })
</script>

<template>
  <a v-if="isExternalLink" v-bind="$attrs" :href="to" target="_blank">
    <slot />
  </a>
  <router-link
    v-else
    v-bind="$props"
    custom
    v-slot="{ isActive, href, navigate }"
  >
    <a v-bind="$attrs" :href="href" @click="navigate" :class="isActive ? activeClass : inactiveClass">
      <slot />
    </a>
  </router-link>
</template>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值