vue 3 第二十九章:路由管理(Vue Router4.x基础知识)

news/2024/12/2 10:14:57/

文章目录

  • 1. Vue Router 的介绍
  • 2. Vue Router 的安装和使用
    • 2.1. 安装
    • 2.2. 使用
  • 3. Vue Router 的路由配置和参数传递
    • 3.1. 路由配置
    • 3.2. 参数传递
      • 3.2.1. props
      • 3.2.2. query
      • 3.3. 访问路由参数
  • 4. Vue Router 的动态路由和嵌套路由
    • 4.1. 动态路由
    • 4.2. 嵌套路由
  • 5. 路由重定向
  • 6. Vue Router 的导航守卫和跳转控制
    • 6.1. 全局导航守卫
      • 6.1.1. 全局前置守卫(beforeEach)
      • 6.1.2. 全局解析守卫(beforeResolve)
      • 6.1.3. 全局后置钩子(afterEach)
    • 6.2. 路由独享的导航守卫(beforeEnter)
    • 6.3. 组件内的导航守卫

1. Vue Router 的介绍

Vue RouterVue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,可以轻松地构建单页面应用程序。Vue Router 允许我们在应用程序中定义路由,然后根据 URL 来匹配路由,并渲染对应的组件

Vue Router 的核心概念包括路由路由器路由视图导航守卫

  • 路由:指 URL组件之间的映射关系
  • 路由器:指管理所有路由的实例
  • 路由视图:指根据 URL 匹配到的组件
  • 导航守卫:指在路由切换时进行的一些处理操作

2. Vue Router 的安装和使用

2.1. 安装

// npm
npm install vue-router@4// yarn 
yarn add vue-router@4

2.2. 使用

在 Vue Router 中,我们可以使用 VueRouter 类来创建一个路由器实例,并使用 router-linkrouter-view 组件来定义路由链接和路由视图。

import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'const router = createRouter({history: createWebHistory(),routes: [{ path: '/', component: Home },{ path: '/about', component: About }]
})const app = createApp({})app.use(router)app.mount('#app')

在上面的例子中,我们使用 createRouter 函数创建了一个路由器实例,并使用 createWebHistory 函数来创建一个基于浏览器历史记录的路由模式。然后,我们定义了两个路由,分别对应 //about 路径。除了上面这种全局创建之外,更推荐的做法是创建一个 router.js 或 router/index.js 文件。

在模板中,我们可以使用 router-link 组件来定义路由链接,例如:

<template><div><!--使用 router-link 组件进行导航 --><!--通过传递 `to` 来指定链接 --><!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签--><router-link to="/">Home</router-link><router-link to="/about">About</router-link></div>
</template>

在上面的例子中,我们使用 router-link 组件来定义 //about 两个路由链接。当用户点击链接时,Vue Router 会根据链接的 to 属性来匹配路由,并渲染对应的组件。

在路由视图中,我们可以使用 router-view 组件来渲染路由组件,例如:

<template><div><!-- 路由出口 --><!-- 路由匹配到的组件将渲染在这里 --><router-view></router-view></div>
</template>

在上面的例子中,我们使用 router-view 组件来渲染路由组件。当用户访问 / 路径时,Home 组件会被渲染到 router-view 组件中;当用户访问 /about 路径时,About 组件会被渲染到 router-view 组件中。

3. Vue Router 的路由配置和参数传递

3.1. 路由配置

在 Vue Router 中,我们可以使用 VueRouter 类来创建一个路由器实例,并使用 routes 属性来定义路由。每个路由都包含 pathcomponent 两个属性,分别表示 URL 和对应的组件。例如,下面的例子中,我们定义了两个路由,分别对应 //about 路径:

import { createRouter, createWebHistory } from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'const routers = [{ path: '/', component: Home },{ path: '/about', component: About }]const router = createRouter({history: createWebHistory(),routes,
})export default router;

3.2. 参数传递

在 Vue Router 中,我们可以通过 URL 来传递参数。URL 参数可以通过 propsquery 两种方式传递。

3.2.1. props

使用 props 传递参数时,我们需要在路由配置中定义 props 函数,返回一个对象,对象的属性名对应组件中的 props 属性名,属性值对应 URL 参数名。例如,下面的例子中,我们定义了一个路由,传递了一个 id 参数:

const router = createRouter({history: createWebHistory(),routes: [{path: '/user/:id',component: User,props: route => ({ id: route.params.id })}]
})

3.2.2. query

使用 query 传递参数时,我们可以在 URL 中添加查询参数,例如 /?id=1。在组件中,我们可以通过 $route.query 来获取查询参数。例如,下面的例子中,我们定义了一个路由,传递了一个 id 参数:

const router = createRouter({history: createWebHistory(),routes: [{path: '/user',component: User,props: route => ({ id: route.query.id })}]
})

3.3. 访问路由参数

注意:在 setup 形式下,不能使用this.$routerthis.$route,作为替代,我们使用useRouteruseRoute函数:

<script setup lang="ts">
import { useRouter, useRoute } from 'vue-router'const router = useRouter()
const route = useRoute()console.log(router)
console.log(route)
</script>

4. Vue Router 的动态路由和嵌套路由

4.1. 动态路由

Vue Router中,我们可以使用动态路由来匹配不同的 URL。动态路由是指包含参数的路由,参数可以通过 : 来定义。例如,我们可以使用 /user/:id 来定义一个动态路由,其中 :id 表示参数。在组件中,我们可以通过 $route.params 来获取参数。例如,下面的例子中,我们定义了一个动态路由,根据不同的ID渲染不同的用户信息:

const router = createRouter({history: createWebHistory(),routes: [{path: '/user/:id',component: User}]
})

在上面的例子中,我们定义了一个 /user/:id 的动态路由,并渲染 User 组件。在 User 组件中,我们可以通过 $route.params.id 来获取 ID

4.2. 嵌套路由

在 Vue Router 中,我们可以使用嵌套路由来组织复杂的页面结构。嵌套路由是指包含子路由的路由。例如,我们可以使用 /user 来定义一个父路由,然后在父路由中包含多个子路由。在组件中,我们可以使用 <router-view> 组件来渲染子路由对应的组件。例如,下面的例子中,我们定义了一个父路由 /user,包含两个子路由 /user/profile/user/posts

const router = createRouter({history: createWebHistory(),routes: [{path: '/user',component: User,children: [{path: 'profile',component: Profile},{path: 'posts',component: Posts}]}]
})

在上面的例子中,我们定义了一个 /user 的父路由,并渲染 User 组件。在 User 组件中,我们使用 <router-view> 组件来渲染子路由对应的组件。在父路由中,我们使用 children 属性来定义子路由。

5. 路由重定向

在某些情况下,我们可能需要将某个路由重定向到另一个路由,例如将 /a 重定向到 /b。我们可以通过在路由配置中使用 redirect 来实现这一功能。

const router = new VueRouter({routes: [{ path: '/a', redirect: '/b' }]
})

我们还可以使用命名路由来实现重定向:

const router = new VueRouter({routes: [{ path: '/a', redirect: { name: 'foo' }}]
})

如果我们需要动态的重定向到一个路由,则可以在 redirect 中使用一个函数来实现:

const router = new VueRouter({routes: [{ path: '/a', redirect: to => {// 动态返回重定向目标return '/b'}}]
})

需要注意的是,如果我们使用了命名路由,那么在重定向时也需要使用命名路由。

6. Vue Router 的导航守卫和跳转控制

Vue Router 中的导航守卫可以用来控制路由的跳转,包括全局导航守卫、路由独享的导航守卫和组件内的导航守卫。

6.1. 全局导航守卫

全局导航守卫会在每次路由跳转时都被调用,包括 beforeEachbeforeResolveafterEach 三个方法。其中,beforeEach 方法用来进行路由跳转前的验证,可以通过 next 方法来进行跳转,例如:

6.1.1. 全局前置守卫(beforeEach)

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。

router.beforeEach((to, from) => {// ...// 返回 false 以取消导航return false
})

每个守卫方法接收两个参数

  • to: 即将要进入的目标
  • from: 当前导航正要离开的路由

可以返回的值如下:

  • false: 取消当前的导航。如果浏览器的URL改变了(可能是用户手动或者浏览器后退按钮),那么URL地址会重置到from路由对应的地址。
  • 一个路由地址: 通过一个路由地址跳转到一个不同的地址,就像你调用router.push()一样,你可以设置诸如replace: truename: 'home'之类的配置。当前的导航被中断,然后进行一个新的导航,就和from一样。
router.beforeEach(async (to, from) => {if (// 检查用户是否已登录!isAuthenticated &&// ❗️ 避免无限重定向to.name !== 'Login') {// 将用户重定向到登录页面return { name: 'Login' }}})

可选的第三个参数 next:
进行路由跳转前的验证,并使用next方法来进行跳转。

router.beforeEach((to, from, next) => {if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })else next()
})

6.1.2. 全局解析守卫(beforeResolve)

在导航被确认之前,和全局后置守卫(beforeEach)相似,我们也可以注册一个全局解析守卫。这个守卫在全局前置守卫 (beforeEach)、路由独享的前置守卫(beforeRouteEnter)之后调用。

与全局前置守卫不同的是,它会在所有异步路由被解析之后调用,也就是在所有懒加载的组件被加载完之后。

const router = new VueRouter({ ... })router.beforeResolve((to, from, next) => {/* 在某些情况下,可能需要等待异步组件加载完成后才能执行后续操作 */next()
})

注意,该守卫不会像全局前置守卫一样,接收一个回调函数来调用 next 方法。相反,你只需要像 beforeEach 一样调用 next 方法,就可以被解析的异步组件所依赖的所有组件都被解析完毕。

6.1.3. 全局后置钩子(afterEach)

和全局前置守卫、全局解析守卫相似,我们也可以注册一个全局后置守卫。这个守卫在每个路由导航结束后被调用,即在所有的组件渲染完成之后,无论导航是成功的还是被中断的。

const router = new VueRouter({ ... })router.afterEach((to, from) => {/* 在这里执行一些操作 */
})

常用于页面分析、动态修改页面标题等。
需要注意的是,这里没有 next 方法,也无法改变导航本身。

6.2. 路由独享的导航守卫(beforeEnter)

除了全局前置守卫和全局解析守卫之外,我们还可以在路由配置上直接定义一个 beforeEnter 守卫。这个守卫只会对当前路由起作用。

const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {// ...}}]
})

beforeEnter 的使用方式与全局前置守卫相同,接收三个参数 (to, from, next),并通过调用 next 方法来决定路由的行为。

需要注意的是,beforeEnter 不会像全局解析守卫一样等待异步组件加载完成后再调用,因此在使用异步组件时需要特别注意。

6.3. 组件内的导航守卫

在组件内部,我们也可以定义导航守卫。和全局导航守卫的使用方式相同,我们可以在组件配置中定义 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave 三个导航守卫。这些守卫不同于全局导航守卫,它们可以访问组件实例 this,因此可以对组件进行更细粒度的控制。

  • beforeRouteEnter: 在路由进入前被调用。此时组件尚未被创建,因此无法访问组件实例 this,但可以通过传递一个回调函数来访问组件实例。
  • beforeRouteUpdate: 在路由更新时被调用(例如,使用相同组件的不同路由)。它可以访问组件实例 this,因此可以在路由更新时更改组件内部的状态。
  • beforeRouteLeave: 在路由离开当前组件时被调用。它可以访问组件实例 this,因此可以在路由离开前执行一些清理操作。
const Foo = {template: `...`,beforeRouteEnter (to, from, next) {// 在路由进入前被调用// 无法访问组件实例 `this`// 但可以通过传递一个回调来访问组件实例next(vm => {// 通过 `vm` 访问组件实例})},beforeRouteUpdate (to, from, next) {// 在路由更新时被调用// 可以访问组件实例 `this`},beforeRouteLeave (to, from, next) {// 在路由离开当前组件时被调用// 可以访问组件实例 `this`}
}

需要注意的是,这些导航守卫只对当前组件起作用,因此如果需要在多个组件中共享相同的导航守卫,仍然需要使用全局导航守卫。


http://www.ppmy.cn/news/139350.html

相关文章

2320. 统计放置房子的方式数-动态规划

统计放置房子的方式数-动态规划 一条街道上共有 n * 2 个 地块 &#xff0c;街道的两侧各有 n 个地块。每一边的地块都按从 1 到 n 编号。每个地块上都可以放置一所房子。 现要求街道同一侧不能存在两所房子相邻的情况&#xff0c;请你计算并返回放置房屋的方式数目。由于答案…

关于佳能IR2320N网络打印机的安装域使用

第一步&#xff1a;首先要为该机器设置一个IP地址&#xff0c;具体方法是&#xff1a;附加管理→系统管理→网络管理→IPv4→IP地址&#xff0c;输入相应的IP地址&#xff0c;子网掩码&#xff0c;默认网关。如果你要查看该机的MAC地址的话&#xff0c;那你也可以在此查看呢。选…

2320. 统计放置房子的方式数

思路&#xff1a; 第一想法用动规&#xff0c;但是不知道如何下手。浅看了一下答案&#xff0c;发现是做过的题。 易知&#xff1a;道路两排的房子摆列互不干扰&#xff0c;只需要保证每一侧的房子间隔排列即可。 所以&#xff0c;最终的结果为 dp[n]*dp[n]。 只需要对一侧…

洛谷P2320 [HNOI2006]鬼谷子的钱袋

https://www.luogu.org/problem/show?pid2320#sub 题目描述全是图 数学思维&#xff0c;分治思想 假设总数为n 从n/21到n的数都可以用1~n的数n/2表示出来 1~n/2的数也可以这样拆分成两份。 一路拆下去即可。 例如n12时&#xff1a; {1 2 3 4 5 6}6{7,8,9,10,11,12} {1,2,3}3{4…

Ardunio开发实例-AM2320温湿度传感器

AM2320温湿度传感器 温湿度组合传感器AM2320数字温湿度传感器是一种已校准的数字信号输出。 采用特殊的温度和湿度采集技术,确保产品具有很高的可靠性和出色的长期稳定性。 传感器由电容式湿度元件和集成的高精度温度测量设备组成,并与高性能微处理器连接。 AM2320使用一条…

HT66F2390/STM32——AM2320温湿度传感器

1、说明 AM2320 数字温湿度传感器采用单总线、标准 IC 两种通信方式。本文主要基于HT66F2390单片机&#xff0c;采用单总线通讯&#xff0c;实现AM2320传感器数据获取。关于AM2320传感器的使用&#xff0c;可参考AM2320产品手册。在文章最后&#xff0c;分享了AM2320的相关资料…

一次恶心的AM2320温湿度传感器调试经历

一次恶心的AM2320温湿度传感器调试经历 前面画了一块MCU和FPGA的PCB板子&#xff0c;主要功能都已经测试通过了&#xff0c;还剩下一个温湿度传感器AM2320的功能没试&#xff0c;本以为网上买的这个模块无非就是引两个引脚出来就完事了&#xff0c;可最后却花了我近两天时间来调…

双节锂电池充电方案芯片IP2320,支持5V输入同步开关升压充电

双节串联锂电池/锂离子电池的升压充电管理方案芯片——英集芯IP2320&#xff0c;集成功率MOS&#xff0c;采用同步开关架构&#xff0c;使其在应用时仅需极少的外围器件&#xff0c;并有效减小整体方案的尺寸&#xff0c;降低BOM成本。 IP2320 集成一个Boost同步升压充电控制器…