文章目录

声明式导航与传参
一、声明式导航
1. 问题
要手动输入地址,切换页面,这样不合理吧?能否点击链接进行跳转呢?
2. 解决方案
vue-router 提供了一个全局组件 router-link ,用于点击跳转,需添加 to 属性指定路径。
实际上
<router-link>组件本质是<a>标签,添加to属性本质是给<a>标签添加href属性。
语法:<router-link to="path值"> xxx </router-link>
javascript
<script setup></script>
<template>
<nav>
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/friend">朋友</router-link>
</nav>
</template>
<style>
nav a {
color: #333;
text-decoration: none;
}
nav a:nth-child(2) {
margin: 0 80px;
}
nav a.router-link-active {
background: red;
color: #fff;
}
</style>
3. 自带高亮类名
使用 <router-link> 跳转后,可以发现当前点击的链接默认加了两个 class 的值:router-link-exact-active 和 router-link-active,我们可以给任意一个 class 属性添加高亮样式即可实现功能,如上面的代码所示。

二、router-link-active 和 router-link-exact-active 的区别
它们的区别在于匹配规则:
router-link-active- 模糊匹配(包含关系)。
- 只要当前路由 以该路径开头,就会添加这个类。
- 例子:
- 链接是
/home - 当前路由是
/home/news - 也会被标记为
router-link-active。
- 链接是
router-link-exact-active- 精确匹配(完全一致)。
- 只有当前路由 完全等于该路径 时才会添加。
- 例子:
- 链接是
/home - 当前路由是
/home/news - 不会加
router-link-exact-active,只有当路由正好是/home时才加。
- 链接是
三、声明式导航传参
1. 需求
在跳转路由时如果需要进行传参,比如:现在我们在发现音乐页,点击去朋友页,并携带 id,方便后续查询详情,如何传参?
2. 传参分类
我们可以通过两种方式,在跳转的时候把所需要的参数传到其他页面中
- 查询参数传参
- 动态路由传参
3. 查询参数传参
在传参时候,有两种格式,一种是字符串形式传参,一种是对象形式传参!
-
字符串
javascript<router-link to="/path?参数名=值"> xxx </router-link> -
对象
javascript<router-link :to="{ path: '/path', query: { 参数名: 值 ... } }"> xxx </router-link>
在接收参数 时候,使用 useRoute() 获取 route 路由对象,通过 route.query 获取到传递过来的参数。
javascript
<script setup>
import { useRoute } from 'vue-router'
// 得到当前激活的路由对象
const route = useRoute()
// 获取查询参数
console.log(route.query.参数名)
</script>
代码示例
App.vue文件:
javascript
<!-- 字符串 -->
<router-link to="/friend?id=10086"> 朋友 </router-link>
<!-- 对象 -->
<router-link :to="{
path: '/friend',
query: {
id: 10086
}
}"> 朋友 </router-link>
Friend.vue文件:
javascript
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.query.id)
</script>
4. 动态路由传参
步骤:
- 配置动态路由
- 动态路由后面的参数可以随便起名,但要有语义

javascript
const router = createRouter({
...
routes: [
...
{
name: 'Friend',
path: '/friend/:fid',
component: Friend
}
]
})
在传参时候,同样有两种格式,一种是字符串形式传参,一种是对象形式传参!
-
字符串
javascript<router-link to="/path/具体值"> xxx </router-link> -
对象
javascript<router-link :to="{ name: 'Friend', params: { 参数名: 具体值 } }"> xxx </router-link>
接收参数时候,和前面不同的是这里要用 route.params 获取传递过来的参数。
javascript
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// 获取动态路由参数
console.log(route.params)
</script>
代码示例
router/index.js文件:
javascript
createRouter({
routes: [
{
name: 'Friend',
path: '/friend/:fid',
component: Friend
}
]
})
App.vue文件:
javascript
<!-- 字符串 -->
<router-link to="/friend/10010"> 朋友 </router-link>
<!-- 对象 -->
<router-link :to="{
name: 'Friend',
params: {
fid: 10010
}
}"> 朋友 </router-link>
Friend.vue文件:
javascript
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params.fid)
</script>
编程式导航与传参
一、编程式导航
1. 问题
如何主动做路由跳转?比如:登录成功自动跳转至首页
2. 解决方案
编程式导航:用 JS 代码跳转路由 ,而不是像声明式导航那样写在模板里的 <router-link>。
3. 语法
通过 useRouter() 获取路由实例 router,然后由 router.push(路径) 添加路由内容。
其中该路由内容可以是字符串形式,也可以是对象形式,这和声明式导航是一样的!
javascript
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
router.push(字符串)
router.push(对象)
</script>
4. 路由对象 vs 路由实例
之前 声明式导航 中使用的是 useRoute() 来创建当前的路由对象,但是 编程式导航 则不一样,使用的是 useRouter() 来创建路由实例,这两者是完全不同的,区别在于一个读数据,一个改数据:
① useRoute()
-
返回 当前路由对象 (等价于
this.$route)。 -
包含的信息:
path、params、query、fullPath、matched等。 -
只读 ,用来获取路由状态,表示 "你此刻在哪"。
-
例子:
javascriptimport { useRoute } from 'vue-router' const route = useRoute() console.log(route.query.page) // 查询参数 console.log(route.params.id) // 动态参数
② useRouter()
-
返回 路由实例 (等价于
this.$router)。 -
提供导航方法:
push(跳转到新地址)、replace(替换当前地址)等。 -
可写 ,用来跳转或修改路由,表示 "你怎么去别的地方"。
-
例子:
javascriptimport { useRouter } from 'vue-router' const router = useRouter() router.push('/home') // 跳转 router.push({ name: 'user', params: { id: 123 } })
代码示例
需求:组件挂载后,延迟2秒,自动从 发现音乐页 跳转至 朋友页。
Find.vue文件:
javascript
<script setup>
import { useRouter } from 'vue-router'
import { onMounted } from 'vue'
const router = useRouter()
// 组件挂载后, 延迟2秒, 自动从 发现音乐页 跳转至 朋友页
onMounted(() => {
setTimeout(() => {
// 1、字符串形式
router.push('/friend')
// 2、对象形式:path属性
router.push({
path: '/friend'
})
// 3、对象形式:name属性
router.push({
name: 'Friend'
})
}, 2000)
})
</script>
二、编程式导航传参
编程式导航与声明式导航的传参和接参方式完全一样,既支持字符串,也支持对象,如下所示:
javascript
// 1、查询参数传参:字符串形式
router.push('/path?参数名=值')
// 2、查询参数传参:对象形式
router.push({
path: '/path',
query:{
参数名: 值
...
}
})
// 3、动态路由传参:字符串形式
router.push('path/参数值')
// 4、动态路由传参:对象形式
router.push({
name: '路由名称',
params: {
参数名: 值
}
})
嵌套与守卫
一、路由嵌套
1. 问题
能否在一个路由页面中,再进行一套路由的切换呢?比如网易云音乐的发现音乐页

2. 步骤
- 这里创建3个二级路由页面组件(Recommend、Ranking、SongList)来举例子
- 然后在路由表数组中,在相应的一级路由规则中,配置
children规则 - 在相应的一级路由页面组件中,给二级路由
<router-view/>出口和导航链接
💥注意事项:
- 二级路由的
path不需要在开头加/ - 做路由跳转的时候要写 完整路径(父路径+当前路径)
- 防止二级路由页面空白,给默认显示的一级路由 添加重定向
代码示例
views/Recommend.vue文件:
javascript
<script setup></script>
<template>
<div class="recommend">
<h5>推荐</h5>
<h5>推荐</h5>
<h5>推荐</h5>
</div>
</template>
<style scoped></style>
views/Ranking.vue文件:
javascript
<script setup></script>
<template>
<div class="ranking">
<h5>排行榜</h5>
<h5>排行榜</h5>
<h5>排行榜</h5>
</div>
</template>
<style scoped></style>
views/SongList.vue文件:
javascript
<script setup></script>
<template>
<div class="songlist">
<h5>歌单</h5>
<h5>歌单</h5>
<h5>歌单</h5>
</div>
</template>
<style scoped></style>
router/index.js文件:
javascript
import Recommend from '@/views/Recommend.vue'
import Ranking from '@/views/Ranking.vue'
import SongList from '@/views/SongList.vue'
const router = createRouter({
history: createWebHashHistory(),
routes: [{
path: '/find',
component: Find,
redirect: '/find/recommend', // 重定向, 防止二级路由空白
// 配置嵌套路由
children: [{
// 二级路由开始, 推荐 path 不加 /
path: 'recommend',
component: Recommend
},{
path: 'ranking',
component: Ranking
},{
path: 'songlist',
component: SongList
}]
}]
})
views/Find.vue文件:
javascript
<script setup></script>
<template>
<div class="find">
<nav>
<!-- 二级路由导航链接 -->
<router-link to="/find/recommend">推荐</router-link>
<router-link to="/find/ranking">排行榜</router-link>
<router-link to="/find/songlist">歌单</router-link>
</nav>
<!-- 二级路由出口 -->
<router-view />
</div>
</template>
<style scoped></style>
二、路由守卫
1. 问题
能否在访问某个路由前,添加权限判断?比如我的音乐页,只有登录了才可以访问。
2. 解决方案
路由(导航)全局前置守卫:每个路由在跳转前都会触发回调函数,可以通过 router.beforeEach() 为这些路由设置判断条件,以此完成权限判断等功能。
javascript
router.beforeEach((to, from) => {
// to: 即将要进入的路由
// from: 当前正要离开的路由
// false 取消导航(不发生跳转)
return false
// 正常放行、正常跳转
return undefined | true
// 重定向到指定的路由
return '/路径'
})
代码示例
router/index.js文件:
javascript
// 用来模拟是否登录
const isLogin = true
router.beforeEach((to, from) => {
// 如果没有登录, 并且还要去 我的音乐页
if(!isLogin && to.path === '/my') {
// 进行提示
alert('请先登录')
// 不放行(不跳转)
return false
}
// 正常放行
return true
})
