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>
实际会被渲染成:
属性
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>
isActive 和 isExactActive
<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参数所执行的路径,可以携带参数 |