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

文章目录

声明式导航与传参

一、声明式导航

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 属性添加高亮样式即可实现功能,如上面的代码所示。

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

  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
})
相关推荐
a1117762 小时前
拼图小游戏(HTML5、CSS3、JavaScript)
javascript·css3·html5
东东5164 小时前
基于ssm的网上房屋中介管理系统vue
前端·javascript·vue.js
harrain5 小时前
什么!vue3.4开始,v-model不能用在prop上
前端·javascript·vue.js
阿蒙Amon10 小时前
TypeScript学习-第7章:泛型(Generic)
javascript·学习·typescript
睡美人的小仙女12710 小时前
Threejs加载环境贴图报错Bad File Format: bad initial token
开发语言·javascript·redis
fanruitian10 小时前
uniapp android开发 测试板本与发行版本
前端·javascript·uni-app
摘星编程11 小时前
React Native + OpenHarmony:Timeline垂直时间轴
javascript·react native·react.js
2501_9445255412 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
jin12332212 小时前
React Native鸿蒙跨平台完成剧本杀组队详情页面,可以复用桌游、团建、赛事等各类组队详情页开发
javascript·react native·react.js·ecmascript·harmonyos