当前位置: 首页 > news >正文

3.2Vue Router路由导航

router-link 默认类样式详解

<router-link> 会根据当前路由($route)与 to 属性的匹配情况,自动添加以下 CSS 类:

1. router-link-active

  • 触发条件:当链接对应的路由 被包含在当前路由中 时添加。
  • 用途:适用于 嵌套路由 的场景。
  • 注意:即使当前路径是 /users/123/users 的链接也会被激活。

2. router-link-exact-active

  • 触发条件:当链接对应的路由 与当前路由完全精确匹配 时添加。
  • 用途:适用于需要 精确匹配 的场景,避免父级路由在子路由激活时也被高亮。

router-link-exact-activerouter-link-active 的子集。也就是说,一个被精确匹配的链接,同时拥有两个类

3. 修改默认样式类名

  • 全局配置 Vue Router 实例
    import Vue from 'vue';
    import Router from 'vue-router';Vue.use(Router);const router = new Router({mode: 'history',base: process.env.BASE_URL,routes: [// ... 路由配置],linkActiveClass: 'my-active-class',       // 修改默认的 active classlinkExactActiveClass: 'my-exact-active-class' // 修改默认的 exact active class
    });export default router;
  •  在单个 <router-link> 上指定自定义类名

    <router-link to="/about" active-class="my-active-class" exact-active-class="my-exact-active-class"
    >About Us
    </router-link>

    路由导航传参:

声明式导航:<router-link>

<router-link> 是 Vue Router 提供的一个组件,用于在模板中创建可点击的链接,从而触发路由跳转。

基本用法

最简单的形式是直接指定一个 to 属性来定义目标路径:

<router-link to="/">Go to Home</router-link>

这会生成一个指向根路径 / 的链接,当用户点击时会导航到对应的视图。

主要属性
  • to (必需): 指定目标路由的位置。可以是一个字符串或一个描述目标位置的对象。

    <!-- 字符串 -->
    <router-link to="home">Home</router-link><!-- 使用对象 -->
    <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
    <!-- 使用字符串路径(原对象形式使用 name 和 params)-->
    <router-link to="/user/123">User</router-link><!-- 带查询参数 -->
    <router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>
    <!-- 带查询参数的字符串形式(原对象形式使用 path 和 query)-->
    <router-link to="/register?plan=private">Register</router-link>
  • replace: 如果设置为 true,则导航不会留下历史记录,也就是说点击后退按钮不会回到这个页面。

    <router-link :to="{ path: '/abc'}" replace>Go to ABC</router-link>
  • append: 设置为 true 时,导航时会在当前路径前追加路径,而不是替换整个路径。

    <router-link :to="{ path: 'relative/path'}" append>Relative Path</router-link>
  • tag: 自定义渲染的标签名,默认为 <a> 标签。

    <router-link to="/foo" tag="li">Foo</router-link>
    <!-- 渲染为 <li>Foo</li> -->

编程式导航详解

1. $router.push()

push() 方法用于导航到新的路由,会向浏览器历史记录栈添加一条新记录。

使用字符串路径

    // 字符串路径
    this.$router.push('/home')// 带查询参数,结果为 /register?plan=private
    this.$router.push('/register?plan=private')
    // 或者使用对象形式
    this.$router.push({ path: '/register', query: { plan: 'private' }})

    查询参数

    query)是以键值对的形式附加在 URL 的末尾,前面有一个问号 ? 分隔符。如果有多个查询参数,则用 & 符号连接。

    http://example.com/user?id=123&name=john

    在这个例子中,id=123name=john 就是两个查询参数。

    params 通常与 RESTful 风格的路由设计紧密相关.

    /users          # 表示所有用户这个资源集合
    /users/123      # 表示 ID 为 123 的单个用户资源
    /users/123/posts # 表示 ID 为 123 的用户的博客文章集合

    使用路径 path 
    // 使用 path
    this.$router.push({ path: '/user' })// path + params 不起作用,params 会被忽略
    // ❌ 错误:/user 不会包含 params
    this.$router.push({ path: '/user', params: { userId: 123 }})// ✅ 正确:使用 query
    this.$router.push({ path: '/user', query: { userId: 123 }})
    // 结果:/user?userId=123
    使用路由名称 name
    // 使用 name 和 params
    this.$router.push({ name: 'user', params: { userId: 123 }})
    // 结果:/user/123 (假设路由配置为 /user/:userId)// 使用 name 和 query
    this.$router.push({ name: 'user', query: { id: 123 }})
    // 结果:/user?id=123

    2. $router.replace()

    replace() 方法与 push() 类似,但不会向 history 添加新记录,而是替换当前记录。

    // 替换当前路由
    this.$router.replace('/home')
    this.$router.replace({ path: '/home' })
    this.$router.replace({ name: 'user', params: { userId: 123 }})

    3. $router.go()

    在 history 记录中前进或后退指定步数。

    // 后退一步
    this.$router.go(-1)// 前进一步
    this.$router.go(1)// 前进三步
    this.$router.go(3)// 如果没有足够的记录,会失败且不报错
    this.$router.go(-100)
    this.$router.go(100)

    路由传参详解

    1. params 传参

    路由配置
    const routes = [{path: '/user/:userId',name: 'user',component: User},{path: '/user/:userId/post/:postId',name: 'user-post',component: UserPost}
    ]
    传递 params
    // 使用 name + params
    this.$router.push({ name: 'user', params: { userId: 123 } 
    })// 传递多个参数
    this.$router.push({ name: 'user-post', params: { userId: 123, postId: 456 } 
    })// 声明式导航
    <router-link :to="{ name: 'user', params: { userId: 123 }}">用户</router-link>
    接收 params
    // 在目标组件中
    export default {created() {console.log(this.$route.params.userId) // 123console.log(this.$route.params.postId) // 456}
    }

    2. query 传参

    传递 query
    // 使用 path + query
    this.$router.push({ path: '/user', query: { userId: 123, name: 'john' } 
    })// 使用 name + query
    this.$router.push({ name: 'user', query: { userId: 123, name: 'john' } 
    })// 声明式导航
    <router-link :to="{ path: '/user', query: { userId: 123 }}">用户</router-link>
    <router-link :to="'/user?userId=123'">用户</router-link>
    接收 query
    // 在目标组件中
    export default {created() {console.log(this.$route.query.userId) // 123console.log(this.$route.query.name)   // john}
    }

    完整案例

    1. 路由配置

    // router/index.js
    import Vue from 'vue'
    import Router from 'vue-router'
    import Home from '@/views/Home.vue'
    import User from '@/views/User.vue'
    import UserProfile from '@/views/UserProfile.vue'
    import UserPosts from '@/views/UserPosts.vue'Vue.use(Router)export default new Router({mode: 'history',routes: [{path: '/',name: 'home',component: Home},{path: '/user',component: User,children: [{path: ':id',name: 'user-profile',component: UserProfile,props: true // 将路由参数作为组件属性传递},{path: ':id/posts',name: 'user-posts',component: UserPosts}]}]
    })

    2. 导航示例

    // Home.vue
    export default {methods: {// 使用 path 导航goToUserByPath() {this.$router.push('/user/123')},// 使用 path + querygoToUserWithQuery() {this.$router.push({path: '/user/123',query: { tab: 'profile', lang: 'zh' }})},// 使用 name + paramsgoToUserByName() {this.$router.push({name: 'user-profile',params: { id: 123 }})},// 使用 name + params + querygoToUserWithParamsAndQuery() {this.$router.push({name: 'user-posts',params: { id: 123 },query: { page: 1, sort: 'date' }})},// 替换导航replaceToUser() {this.$router.replace({name: 'user-profile',params: { id: 123 }})}}
    }

    3. 接收参数

    // UserProfile.vue
    export default {// 使用 props 接收参数props: ['id'],created() {// 通过 $route 接收 paramsconsole.log('User ID:', this.$route.params.id)// 通过 $route 接收 queryconsole.log('Tab:', this.$route.query.tab)console.log('Language:', this.$route.query.lang)// 使用 props 接收(推荐)console.log('Props ID:', this.id)},watch: {// 监听路由变化(适用于同一个组件内不同参数的切换)'$route'(to, from) {if (to.params.id !== from.params.id) {this.fetchUserData(to.params.id)}}},methods: {fetchUserData(id) {// 根据新的用户ID获取数据}}
    }

    重要注意事项

    1. path 与 params 的限制

      • 当使用 path 时,params 会被忽略
      • 需要使用 query 来传递参数
    2. name 与 params 的优势

      • 更安全,不受路由路径变化影响
      • 可以正确传递参数
    3. 响应路由参数变化

      • 组件被复用时,created 钩子不会被调用
      • 需要使用 watch 监听 $route 变化
    4. 编程式导航的返回值

      • push() 和 replace() 返回一个 Promise
      • 可以处理导航成功或失败的情况
    this.$router.push('/home').then(() => {// 导航成功
    }).catch(err => {// 导航被阻止或出错if (err.name !== 'NavigationDuplicated') {console.log(err)}
    })

    通过掌握这些路由导航和传参的方法,你可以构建出功能丰富、用户体验良好的单页应用。

    $route 

    $route 监听不需要设置 deep: true

    1. $route 对象的特性

      • $route 是响应式的,每当 URL 发生变化(例如通过点击链接或调用 $router.push()),Vue Router 都会更新 $route 对象,并触发相关的侦听器。
      • $route 包含了诸如 pathnameparamsquery 等属性,这些属性代表了当前路由的状态。
    2. 监听 $route 变化的目的

      • 通常监听 $route 的目的是为了根据新的路由信息(如参数、查询等)执行某些操作,比如加载新数据或改变页面内容。
      • 因为 Vue Router 在路由发生变化时会直接替换整个 $route 对象,而不是修改其内部属性,所以你只需要监听 $route 本身的变化即可,而无需深入检查 $route 内部属性的变化。
    3. 为什么不需要 deep: true

      • 当路由发生跳转时,Vue Router 实际上是在替换整个 $route 对象,而不是修改它的某个属性。这意味着,如果你监听了 $route,那么每次路由变化都会触发监听器,无论这个变化是发生在 paramsquery 还是其他属性上。
      • 设置 deep: true 主要是为了监听对象内部深层次的属性变化。然而,在 $route 的情况下,由于它是作为一个整体被替换的,所以不需要这样做。简单地监听 $route 就足够捕捉到所有的路由变化了。
    http://www.lryc.cn/news/615083.html

    相关文章:

  • B.10.01.3-性能优化实战:从JVM到数据库的全链路优化
  • 区块链密码学简介
  • (LeetCode 每日一题) 231. 2 的幂 (位运算)
  • 基于clodop和Chrome原生打印的标签实现方法与性能对比
  • 通过 SCP 和 LXD 配置迁移 CUDA 环境至共享(笔记)
  • 数据标准化与归一化的区别与应用场景
  • FAN5622SX 四通道六通道电流吸收线性LED驱动器,单线数字接口 数字式调光, 2.7 → 5.5 V 直流直流输入, 30mA输出FAN5622S
  • C++ unordered_map 和 unordered_set 的使用
  • 新手向:Python开发简易待办事项应用
  • 【JS-8-Json】深入理解JSON语法及Java中的JSON操作
  • Visual Studio Code (v1.103) 中 GitHub Copilot 最新更新!
  • [TryHackMe]Challenges---Game Zone游戏区
  • 避不开的数据拷贝(2)
  • 第二十天:数论度量
  • 【面试场景题】通过LinkedHashMap来实现LRU与LFU
  • C++隐式转换的魔法与陷阱:explicit关键字的救赎
  • 软件工程总体设计:从抽象到具体的系统构建之道
  • Python基础教程(六)条件判断:引爆思维Python条件判断的九层境界
  • 轻量化阅读应用实践:21MB无广告电子书阅读器测评
  • MySQL(188)如何使用MySQL的慢查询工具?
  • Spring Boot 2 集成 Redis 集群详解
  • 聊聊经常用的微服务
  • MBR分区nvme固态硬盘安装win7--非UEFI启动和GPT分区
  • day30-HTTP
  • 大语言模型提示工程与应用:LLMs文本生成与数据标注实践
  • 在Docker中下载RabbitMQ(详细讲解参数)
  • docker基础前置
  • STM32H503不同GPIO速度配置(HAL库)对应的最高速度
  • 【linux基础】Linux 文本处理核心命令指南
  • 麒麟系统 安装vlc