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

这篇具有很好参考价值的文章主要介绍了vue 3 第二十九章:路由管理(Vue Router4.x基础知识)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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 routes = [
   { 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`
  }
}

需要注意的是,这些导航守卫只对当前组件起作用,因此如果需要在多个组件中共享相同的导航守卫,仍然需要使用全局导航守卫。文章来源地址https://www.toymoban.com/news/detail-467018.html

到了这里,关于vue 3 第二十九章:路由管理(Vue Router4.x基础知识)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 路由器工作原理(第二十九课)

    路由器工作原理(第二十九课) 一图胜过千言 1) 路由:数据从一个网络到另外一个网络之间转发数据包的过程称为路由 2) 路由器:连接不同网络,实现不同网段之间的通信 3)路由表:路由器选择数据的传输路径的依据

    2024年02月14日
    浏览(38)
  • 【Vue3 第十九章】插槽 slot

    数字化管理平台 Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus 权限系统-商城 个人博客地址 在某些场景中,我们可能想要为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。这就用到了插槽。 插槽是子组件中的提供给父组件使用的一个占位符,用 slot 表示,父组件可以

    2024年02月09日
    浏览(39)
  • Vue2 第二十节 vue-router (四)

    1.全局前置路由和后置路由 2.独享路由守卫 3.组件内路由守卫 4.路由器的两种工作模式 路由 作用:对路由进行权限控制 分类:全局守卫,独享守卫,组件内守卫 ① 前置路由守卫:每次路由切换之前被调用或者初始化的时候被调用  next() : 继续执行 meta是路由元信息,是路由

    2024年02月14日
    浏览(32)
  • 【从零开始学习JAVA | 第二十九篇】Stream流

    目录 前言: Stram流: 设计目标: 使用步骤: 1.先得到一条Stream流,并把数据放上去。 2.利用Stream流中的各种API进行操作。 使用Stream流的注意事项: 总结:         本文我们将学习Stream流,他就像流水线一样,可以对我们要处理的对象进行逐步处理,最终达到我们想要的效果

    2024年02月17日
    浏览(46)
  • 【三十天精通Vue 3】 第二十二天 Vue 3的UI框架详解

    ✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: 三十天精通 Vue 3

    2024年02月02日
    浏览(43)
  • vue3第二十一节(新增编译宏defineExpose)

    引言 :在 vue2 中我们可以使用 this.$refs.xxx 调用组件内部的属性或者方法,同时子组件也可以使用 this.$parent.xxx 调用父组件的属性和方法; 但是 当我们在 setup 语法糖中,因为此时的组件 默认是关闭即组件是私有的 ,故使用 $parent.xxx 或者 $children.xxx 是 无法获取到对应的实例

    2024年04月24日
    浏览(40)
  • vue 3 第二十六章:样式(scoped及样式穿透)

    在 Vue 中,我们可以使用 scoped 特性来给组件的样式添加作用域。通过为组件的 style 标签添加 scoped 特性,我们可以确保组件的样式仅应用于该组件的模板中,而不会影响其他组件或全局样式。 在上面的例子中, .example 类的样式只会应用于该组件的模板中,而不会影响其他组

    2024年02月06日
    浏览(75)
  • vue 3 第二十七章:样式(动态class、动态style)

    在 Vue 中,我们可以使用动态绑定语法来动态地添加类名或样式。本章将介绍 Vue 3 中如何使用动态绑定语法来动态地添加类名或样式。 在 Vue 中,我们可以使用 :class 或 v-bind:class 指令来动态地添加类名。例如,下面的例子中,我们可以根据 isActive 的值动态地为元素添加 act

    2024年02月07日
    浏览(43)
  • JavaScript从入门到精通系列第二十九篇:正则表达式初体验

      文章目录 一:正则表达式 1:简介 2:正则表达式 3:检查字符串         正则表达式应用的场景是什么呢?比方说检查客户注册的电子邮件的格式的标准性。让计算机基于固定的格式,去检测用户输入的电子邮件地址是不是正确的电子邮件地址。         正则表达式用于

    2024年02月06日
    浏览(57)
  • 【三十天精通Vue 3】第二十七天 如何用Vue 3和TensorFlow.js实现人脸识别Web应用?

    ✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: 三十天精通 Vue 3

    2024年02月03日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包