首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Vue】声明式导航与传参 && 编程式导航与传参 && 嵌套与守卫

【Vue】声明式导航与传参 && 编程式导航与传参 && 嵌套与守卫

原创
作者头像
lirendada
发布2026-02-03 07:05:15
发布2026-02-03 07:05:15
570
举报
文章被收录于专栏:前端前端

声明式导航与传参

一、声明式导航

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-activerouter-link-active,我们可以给任意一个 class 属性添加高亮样式即可实现功能,如上面的代码所示。

二、router-link-activerouter-link-exact-active 的区别

它们的区别在于匹配规则:

  1. router-link-active
    1. 模糊匹配(包含关系)。
    2. 只要当前路由 以该路径开头,就会添加这个类。
    3. 例子:
      • 链接是 /home
      • 当前路由是 /home/news
      • 也会被标记为 router-link-active

2. router-link-exact-active

  1. 精确匹配(完全一致)。
  2. 只有当前路由 完全等于该路径 时才会添加。
  3. 例子:
    • 链接是 /home
    • 当前路由是 /home/news
    • 不会加 router-link-exact-active,只有当路由正好是 /home 时才加。

三、声明式导航传参

1. 需求

在跳转路由时如果需要进行传参,比如:现在我们在发现音乐页,点击去朋友页,并携带 id,方便后续查询详情,如何传参?

2. 传参分类

我们可以通过两种方式,在跳转的时候把所需要的参数传到其他页面中

  1. 查询参数传参
  2. 动态路由传参

3. 查询参数传参

传参时候,有两种格式,一种是字符串形式传参,一种是对象形式传参!

  1. 字符串
    代码语言:javascript
    复制
    <router-link to="/path?参数名=值"> xxx </router-link>

2. 对象

代码语言: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. 动态路由传参

步骤:

  1. 配置动态路由
  2. 动态路由后面的参数可以随便起名,但要有语义
代码语言:javascript
复制
const router = createRouter({
  ...
  routes: [
    ...
    {
      name: 'Friend',
      path: '/friend/:fid',
      component: Friend
    }
  ]
})

传参时候,同样有两种格式,一种是字符串形式传参,一种是对象形式传参!

  1. 字符串
    代码语言:javascript
    复制
    <router-link to="/path/具体值"> xxx </router-link>

2. 对象

代码语言: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)。
  • 包含的信息:pathparamsqueryfullPathmatched 等。
  • 只读,用来获取路由状态,表示 "你此刻在哪"
  • 例子:
    代码语言:javascript
    复制
    import { useRoute } from 'vue-router'
    
    const route = useRoute()
    console.log(route.query.page)  // 查询参数
    console.log(route.params.id)   // 动态参数
useRouter()
  • 返回 路由实例(等价于 this.$router)。
  • 提供导航方法:push(跳转到新地址)、replace(替换当前地址)等。
  • 可写,用来跳转或修改路由,表示 "你怎么去别的地方"
  • 例子:
    代码语言:javascript
    复制
    import { 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. 步骤

  1. 这里创建3个二级路由页面组件(Recommend、Ranking、SongList)来举例子
  2. 然后在路由表数组中,在相应的一级路由规则中,配置 children 规则
  3. 在相应的一级路由页面组件中,给二级路由 <router-view/> 出口和导航链接

💥注意事项:

  1. 二级路由的 path 不需要在开头加 /
  2. 做路由跳转的时候要写 完整路径(父路径+当前路径)
  3. 防止二级路由页面空白,给默认显示的一级路由 添加重定向

代码示例

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
})

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 声明式导航与传参
    • 一、声明式导航
      • 1. 问题
      • 2. 解决方案
      • 3. 自带高亮类名
    • 二、router-link-active 和 router-link-exact-active 的区别
    • 三、声明式导航传参
      • 1. 需求
      • 2. 传参分类
      • 3. 查询参数传参
      • 4. 动态路由传参
  • 编程式导航与传参
    • 一、编程式导航
      • 1. 问题
      • 2. 解决方案
      • 3. 语法
      • 4. 路由对象 vs 路由实例
      • 代码示例
    • 二、编程式导航传参
  • 嵌套与守卫
    • 一、路由嵌套
      • 1. 问题
      • 2. 步骤
      • 代码示例
    • 二、路由守卫
      • 1. 问题
      • 2. 解决方案
      • 代码示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档