vue3学习 --- vue-router(2)

1,099 阅读3分钟

router-link的v-slot

router-link在默认情况下,会将元素渲染为a标签,如果我们需要渲染为其它元素

在vue-router3.x的时候,router-link有一个tag属性,可以决定router-link到底渲染成什么元素

但是在vue-router4.x开始,该属性被移除了,而给我们提供了更加具有灵活性的v-slot的方式来定制渲染的内容

基本使用

<router-link to="/about">
  <!-- router-link的slot中可以存放元素 -->
  <button>about</button>
</router-link>
<router-link to="/about">
  <!-- router-link的slot中可以存放组件 -->
  <Foo />
</router-link>
<router-link to="/about">
  <!-- router-link的slot中可以存放多个元素和组件 -->
  <button>about</button>
  <button>foo</button>
  <Foo />
</router-link>

custom

默认情况下,vue-router只是在我们所有元素的外边包裹上了一个a标签,并通过a标签进行路由的跳转

<router-link to="/about">
  <h2>about</h2>
</router-link>

实际会被渲染成:

IuibdL.png

属性

vue-router通过作用域插槽的方式,为vue-router的slot提供了一系列的属性,用于扩展vue-router的相关功能

href

<router-link to="/about" v-slot="props">
  <!-- href属性,表示的就是需要跳转的路由 --- 在这里就是/about  -->
  <h2>{{ props.href }}</h2>
</router-link>

route

<router-link to="/about" v-slot="props">
  <!--
  	route就是我们的路由对象
  	是对我们的路由对象进行标准化处理(扩展)过后的对象
    在这里就是对应的about的Route对象
  -->
  <h2>{{ props.route }}</h2>
</router-link>

isActiveisExactActive

<router-link to="/about" v-slot="props">
  <!--
    如果当前路由和需要跳转过去的路由匹配的时候, isActive就显示为true
    可以认为有router-link-active样式的时候 isActive的值就是true
  -->
  <h2>{{ props.isActive }}</h2>

  <!--
    如果当前路由和需要跳转过去的路由精确匹配的时候, isExactActive就显示为true
    可以认为有router-link-exact-active样式的时候 isExactActive的值就是true
  -->
  <h2>{{ props.isExactActive }}</h2>
</router-link>

navigate 函数

默认情况下,vue-router会通过在我们的元素外部包裹a标签,来达到路由跳转的目的

但是有的时候,我们不希望vue-router帮我们包裹a标签,此时可以使用custom属性

<router-link to="/about" custom>
  <h2>about</h2>
</router-link>

<!-- 最终会被渲染为 -->
<h2>about</h2>

但是这样, 就失去了路由跳转的功能,因为此时是自定义模式,路由的跳转需要我们自己去指定那个元素需要进行路由跳转

此时就可以使用navigate函数

<router-link to="/about" v-slot="{ navigate }" custom>
  <!--
    navigate函数本质上就是在我们点击的时候,
    使用$router.push方法,来帮助我们进行路由的跳转
    是一个语法糖函数
  -->
  <h2 @click="navigate">about</h2>
</router-link>

router-view的v-slot

router-view也提供给我们一个插槽

  • Component: 要渲染的组件
  • route: 解析出的标准化路由对象

Component

<router-view v-slot="props">
  <!-- props.Component中存放的就是实际被放置在这里的组件 -->
  <!-- Component中的C是大写的 -->
  <component :is="props.Component" />
</router-view>

案例 --- 组件切换之间的动效

<template>
  <div>
    <router-link to="/home">home</router-link>
    <router-link to="/about">about</router-link>

    <router-view v-slot="props">
      <transition name="fade" mode="out-in">
        <component :is="props.Component" />
      </transition>
    </router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style scoped>
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 1s ease;
}
</style>

案例2--组件切换时候进行缓存

<router-view v-slot="props">
  <keep-alive>
    <component :is="props.Component" />
  </keep-alive>
</router-view>

动态修改路由

动态添加路由

某些情况下我们可能需要动态的来添加路由

  • 路由可以通过name来识别
  • 这个时候我们可以使用一个方法 addRoute --- 参数类型是route对象

添加一级路由

// 在路由器上新增路由 --- 第一个参数省略的时候,就是添加一级路由
router.addRoute({
  path: '/category',
  component: () => import('../src/pages/Category.vue'),
  children: [ ... ]
})

添加子路由

router.js

  {
    path: '/category',
    name: 'category',
    component: () => import('../pages/Category.vue')
  }
// 参数1: 路由的名称,即route对象中配置的name属性
// 参数2: route对象
router.addRoute('category', {
  path: 'fruit',
  component: () => import('../src/pages/Fruit.vue'),
  children: [ ... ]
})

动态删除路由

方法1 --- 使用新的路由替换旧的路由

router.addRoute({
  path: '/category',
  name: 'category',
  component: () => import('../src/pages/Category.vue')
})

// 只要name相同即可,那么vue-router就会将他们视为一个路由
router.addRoute({
  path: '/fruit',
  name: 'category',
  component: () => import('../src/pages/Fruit.vue')
})

方法2 --- removeRoute

// 参数为路由对象的name属性的值
router.removeRoute('category')

方法3 --- 使用addRoute方法返回的函数

const removeRoute = router.addRoute({
  path: '/category',
  name: 'category',
  component: () => import('../src/pages/Category.vue')
})

removeRoute()

其它方法

hasRoute

// 参数为route对象的name属性
// 如果没有传递参数的时候,默认的返回值是false
console.log(router.hasRoute('category'))

getRoutes

// 获取所有的路由对象 ---  其中嵌套的路由会被拍平
// 例如 有路由`/config` 和 其子路由`/config/info`
// 此时获取的结果为 [{path: '/config', ... }, { path: '/config/info', ... }]
console.log(router.getRoutes())

路由导航守卫

vue-router在路由跳转的过程中,提供了一些生命周期回调函数,可以让我们在路由跳转的各个环节进行我们需要的操作, 具体的生命周期钩子可以查看官网

比如: 我们可以在进入页面之前判断用户是否已经登录,没有登录的时候,直接跳转到登录页面,这时候我们就可以使用其中的beforeEach钩子函数,而这个过程就被称之为路由导航守卫

router.beforeEach((to, from) => {
  console.log('路由跳转了') // 任何的路由跳转都会触发跳转
  console.log('to', to) // 即将进入的路由Route对象
  console.log('from', from) // 即将离开的路由Route对象
})

beforeEach函数可以有以下的返回值

类型说明
false取消当前导航
return undefined 或者 什么都不返回进行默认跳转
代表路径的字符串跳转到字符串所指向的那个路径
Route对象 (类似于{ path: 'xxx', query: 'xxx' })跳转到路由对象的path参数所执行的路径,可以携带参数