一文详解Vue3中如何使用Vue Router
作者:九仞山
前言
Vue Router是一个官方的Vue.js路由管理器,它与 Vue.js 核心深度集成,通过它可以轻松地为单页应用程序(SPA)提供路由管理和导航功能。今天我们就来聊一聊Vue 3中使用Vue Router的那些事儿。
安装和配置Vue Router
安装Vue Router
安装Vue Router只需要在vue项目中打开终端,输入如下命令即可安装:
npm 方式安装
npm install vue-router@4
yarn方式安装
yarn add vue-router@4
配置Vue Router
为了便于我们后面代码维护和管理,我们一般将路由相关的代码统一放到一个文件夹中。因此,配置Vue Router的步骤如下:
- 在src文件夹新建一个router文件夹,在该文件夹下新建index.js文件
- 在index.js中引入vue-router中的createRouter 和 createWebHashHistory 方法,引入页面文件
import { createRouter,createWebHashHistory } from "vue-router"; import Home from '../views/Home.vue' import About from '../views/About.vue' import List from '../views/List.vue' import Detail from '../views/Detail.vue'
- 在index.js中定义一个routes数组,在里面定义路由规则
const routes = [ { path:'/home', name:Home, component:Home }, { path:'/about', component:About }, { path:'/list', component:List }, { path:'/detail', component:Detail }, { path:'/', redirect:'/home' } ]
- 在index.js中使用createRouter创建路由实例,并配置路由模式和上面定义的路由规则
const router = createRouter({ history:createWebHashHistory(), routes })
- 在index.js的最后,使用export default 将上面创建的路由实例导出
export default router
- 注册路由:在main.js中导入上面创建的路由文件,并使用app.use注册路由
import router from './router' const app = createApp(App) app.use(router) //注册路由 app.mount('#app')
- 在组件中使用路由组件
在App.vue中使用<router-view>
组件来渲染要显示的组件,在Tabbar组件中使用<router-link>
组件生成链接
App.vue组件中代码
<template> <Title></Title> <router-view></router-view> <Tabbar></Tabbar> </template> <script setup> import Tabbar from './components/Tabbar.vue'; import Title from './components/Title.vue'; </script> <style scoped> </style>
Tabbar组件中代码
<template> <div> <router-link to="/">Home</router-link> <router-link to="/list">List</router-link> <router-link to="/about">About</router-link> </div> </template> <script setup> </script> <style scoped> div { position: fixed; bottom: 0; width: 100%; height: 50px; line-height: 50px; text-align: center; display: flex; justify-content: space-around; } </style>
至此,我们就完成了路由的配置与搭建,运行程序,刷新浏览器,可以看到页面已经可以正常跳转,实现了路由功能。
虽然上面我们已经实现了一个完整的路由场景搭建,但是我们还是要对Vue Router的基础知识进行深入的了解,方便我们更好的理解和使用Vue Router。下面对Vue Router中的一些基本概念进行介绍。
Vue Router的基本概念
路由器:Vue Router 提供了一个路由器,用于管理应用程序中的路由。Vue Router 实例化一个 Vue Router 对象,注册路由规则,并以它为中心连接其他组件。
路由:路由是分发到不同组件的 URL 地址。在 Vue Router 中,路由通常是由 path 规则和相应的组件定义的。当浏览器的 URL 匹配到路由的 path 后,相应的组件将会被加载到页面中。路由的信息可以从 route 对象中获取。
路由规则:路由规则是由 path、component、name、meta、props 等属性组成的。其中,path 表示 URL 的路径,component 表示要渲染的组件,name 表示路由名称,meta 表示路由的元数据,props 表示路由 props 数据。路由规则可以注册到 Vue Router 中。
导航守卫:导航守卫是在路由跳转时执行的钩子函数,用于控制路由的访问权限、处理路由跳转前后的逻辑等。在 Vue Router 中,对于选项式 API,常用的导航守卫有 beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave 等;对于使用组合 API 和 setup 函数来编写组件的,可以通过 onBeforeRouteUpdate 和 onBeforeRouteLeave 分别添加 update 和 leave 守卫。
Vue Router 的配置项介绍
我们在使用Vue Router 中的createRouter创建router对象时,其为我们提供了很多配置项,带完整配置项的示例代码如下:
const router = createRouter({ history: createWebHashHistory(), routes: [], scrollBehavior: () => ({ top: 0, left: 0 }), linkActiveClass: 'active', linkExactActiveClass: 'exact-active', parseQuery: null, stringifyQuery: null, fallback: true })
上面代码中各个配置项的含义如下:
history
:指定路由的 history 模式,目前支持createWebHistory()
和createWebHashHistory()
模式。routes
:定义路由规则的数组,每一个路由规则都是一个对象,包含path
、name
、component
和meta
等属性。scrollBehavior
:指定路由切换时滚动行为的配置函数。该函数返回一个包含x
和y
属性的对象,表示页面跳转后滚动的位置。linkActiveClass
:指定激活状态的链接的 class 名称,默认为'router-link-active'
。linkExactActiveClass
:指定精确匹配的激活状态的链接的 class 名称,默认为'router-link-exact-active'
。parseQuery
和stringifyQuery
:用于配置路由的查询参数解析和序列化函数。通常情况下,我们不需要额外配置这两个函数,因为 Vue Router 已经提供了默认的实现。fallback
:用于配置是否开启 HTML5 History 模式的回退机制。默认值为true
,表示当路由不匹配时,将自动回退到历史记录中的上一个路由。
上面的配置项中,我们一般只需要配置history和routes两个选项就可以了,其它选项了解即可
routes中的配置项介绍
在 Vue Router 中,路由规则的配置是通过 routes
属性来实现的。routes
属性中常用的配置如下:
name
:路由规则的名字。可以用于编程式导航和组件内部的路由跳转。path
:路由的路径,可以包含动态参数和正则表达式。例如,/user/:id
表示用户页面,:id
是一个动态参数。redirect
:路由的重定向规则。例如,{ path: '/', redirect: '/home' }
表示路由根路径的重定向。component
:路由对应的组件。可以是一个普通的组件类或异步加载的组件。children
:当前路由的子路由。可以是一个路由规则数组,也可以是一个函数,动态生成路由规则。meta
:路由的元信息,用于描述路由的一些额外信息。例如,路由是否需要登录、权限鉴定等。components
:路由对应的多个命名视图组件。
路由跳转
通过Vue Router,我们可以通过router-link
组件的to方法和使用router.push
函数以编程方式两种方法导航到路由。
使用 router-link组件
使用router-link
组件实现路由跳转,我们只需要将菜单按钮使用router-link
组件包裹,并在上面使用to方法即可进行跳转,示例代码如下:
<div> <router-link to="/">Home</router-link> <router-link to="/list">List</router-link> <router-link to="/about">About</router-link> </div>
使用router.push函数
使用router.push
函数以编程方式实现路由跳转,我们只需要在普通按钮上绑定click事件,并在事件中调用router.push()
方法即可实现跳转,示例代码如下:
<template> <div> <router-link to="/">Home</router-link> <router-link to="/list">List</router-link> <router-link to="/about">About</router-link> <button @click="gotoAbout"> 关于 </button> </div> </template> <script setup> import { useRouter } from 'vue-router' const router = useRouter() const gotoAbout = () => { router.push('/about') } </script>
使用 router.push
方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。
事实上,当我们点击 <router-link>
时,Vue Router 内部会调用这个方法,所以点击 <router-link :to="...">
相当于调用 router.push(...)
router.push()
方法中的参数可以是一个字符串路径,或者一个描述地址的对象。
// 字符串路径 router.push('/users/eduardo') // 带有路径的对象 router.push({ path: '/users/eduardo' }) // 命名的路由,并加上参数,让路由建立 url router.push({ name: 'user', params: { username: 'eduardo' } }) // 带查询参数,结果是 /register?plan=private router.push({ path: '/register', query: { plan: 'private' } }) // 带 hash,结果是 /about#team router.push({ path: '/about', hash: '#team' })
路由传参
在Vue Router中,可以通过以下方式进行路由传参和获取参数
- 通过路由路径传递参数:在路由配置中使用动态路由匹配(Dynamic Route Matching),例如:
const routes= [ { path: '/detail/:id', name: 'Detail', component: Detail } ]
在路由路径中使用冒号表示参数,参数值会被放入route.params
对象中。我们可以通过调用route.params
获取参数,如访问地址为/detail/123,则我们可以通过route.params.id获取值为"123"。
- 通过query参数传递参数:在路由跳转时使用query参数,例如:
// 在组件中跳转 router.push({ path: '/detail', query: { id: 123 } }) // 在模板中跳转 <router-link to="/detail?id=123">Detail</router-link>
在路由中使用query参数时,参数值会被放入route.query
对象中。我们可以通过route.query获取参数。例如,访问地址为/detail?id=123,则我们可以通过route.query.id获取值为"123"。
- 在路由配置中通过props选项传递参数。例如:
const routes= [ { path: '/detail/:id', name: 'Detail', component: Detail, props: { id: 123 } } ]
在组件中可以直接使用props接收参数
- 在路由配置中通过meta选项传递参数。例如:
const routes= [ { path: '/detail/:id', name: 'Detail', component: Detail, meta: { id: 123 } } ]
在组件中可以通过route.meta获取参数,
动态路由
动态路由是指将一个路由的一部分作为参数来构建的路由。例如,如果我们要为每个用户创建一个单独的页面,我们可以使用动态路由,创建一个路径为/users/:userId
的路由,其中:userId
是一个参数。
动态路由在定义路由时使用冒号(:
)来表示参数。定义动态路由需要使用path
方式定义。例如,要定义一个动态路由,我们可以这样写:
{ path: '/users/:userId', name: 'user', component: User }
在上面的代码中,路径中的:userId
表示一个参数,它可以从路由对象的params
属性中获取。在组件中可以这样读取userId
:
console.log(route.params.userId)
在使用动态路由时,Vue Router还支持使用可选的参数和正则表达式来定义路由。例如,可以这样定义一个包含可选参数的动态路由:
{ path: '/users/:userId/:postId?', name: 'post', component: Post }
在上面的代码中,路径中的postId
参数是可选的,我们在它后面加一个问号代表可选参数。现在,如果路径是/users/123
,那么postId
将是undefined
;如果路径是/users/123/456
,那么postId
将是456
。
嵌套路由
嵌套路由允许我们在一个父级路由下嵌套多个子路由,从而形成更加复杂的页面结构。
要定义嵌套路由,我们可以在父级路由的routes
数组中定义一个子路由对象数组,每个子路由对象都包含一个path
和一个component
属性,表示当前子路由的访问路径和对应的组件。同时,我们还可以在子路由对象中定义子路由的子路由,从而形成嵌套的路由结构。
我们使用配置项children
表示路由的嵌套关系,如下示例代码:
const routes = [ { path: '/', component: Home, children: [ { path: 'about', component: About }, { path: 'contact', component: Contact } ] } ]
在上面的代码中,我们定义了一个名为Home
的组件作为父级路由的组件,并在children
数组中定义了两个子路由:About
和Contact
。这样,当用户访问/about
或/contact
时,Vue Router 就会渲染对应的子组件,并将其嵌套在Home
组件内。
命名路由
命名路由可以为路由设置一个名称,以便在代码中进行引用和跳转。使用命名路由可以让代码更加清晰易懂,尤其是在需要跳转到具有动态参数的路由时。
要定义命名路由,我们可以在路由对象中使用name
属性来指定路由的名称,例如:
const routes = [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/user/:id', name: 'user', component: User } ]
在上面的代码中,我们为三个路由分别指定了名称:home
、about
和user
。然后,在代码中,我们可以通过这些名称来生成对应的路由链接或路由跳转,例如:
<router-link :to="{name: 'home'}">Home</router-link> <router-link :to="{name: 'about'}">About</router-link> <router-link :to="{name: 'user', params: {id: '123'}}">User 123</router-link> router.push({name: 'home'}) router.push({name: 'user', params: {id: '456'}})
在上面的代码中,我们分别使用了<router-link>
组件和router.push()
方法来跳转到具有命名路由的路由。其中,使用params
属性可以动态指定路由中的参数。
命名路由在需要动态传递参数的情况下使用非常方便。
路由守卫
路由守卫是一种函数,在路由的各个阶段被调用,可以用于拦截路由的访问或对路由进行一些操作。我们可以使用路由守卫来控制路由的跳转和访问权限。
在路由守卫中,我们通常会用到三个参数:to
、from
和next
。
to
:表示即将要跳转的目标路由对象,包含路由的路径、参数和查询字符串等信息。from
:表示当前路由对象,即正在离开的路由对象。next
:是一个函数,用于进行路由控制和跳转。当调用next
函数时,路由会继续向下执行。我们可以通过next
函数来控制路由的行为,例如渲染组件、跳转路由、取消操作等。
几种使用next
函数的情况
next()
: 表示继续执行下一个路由守卫。next(false)
: 表示取消当前的路由跳转。next('/path')
: 表示跳转到指定的路由路径。next(error)
: 表示在路由跳转过程中发生了错误,例如权限不足等。
需要注意的是,在使用路由守卫时,我们需要显式地调用next
函数来控制路由的跳转和功能,否则路由不会继续向下执行。在不同的守卫中,next
函数的行为和功能也会有所不同,需要根据具体的场景进行调用。
Vue Router中的路由守卫分为全局路由守卫和路由独享守卫:
全局路由守卫
全局路由守卫是在整个应用中都生效的守卫,可以用于拦截所有的路由操作。在Vue Router@4中,全局守卫有三个:beforeEach
、beforeResolve
和afterEach
。
beforeEach
: 在路由跳转之前执行,可以用于进行全局的访问控制或重定向跳转等操作。beforeResolve
: 在路由跳转完成前执行,可以用于等待异步路由组件加载完成或在路由跳转前进行一些操作。afterEach
: 在路由跳转完成后执行,可以用于对页面进行一些操作,例如监测页面埋点或修改页面标题等。
一个验证用户是否登录的路由守卫示例代码如下
router.beforeEach((to, from, next) => { if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' }) else next() })
上面代码中,如果用户没有登录,则页面跳转到Login页面,如果已经登录,则执行next()跳转
路由独享守卫
路由独享守卫仅对当前路由生效,可以用于限制或增强某个路由的访问权限。在Vue Router@4中,路由独享守卫有两个:beforeEnter
和leaveGuard
。
beforeEnter
: 在进入当前路由之前执行,可以用于增强当前路由的访问权限或进行相关操作。leaveGuard
: 在离开当前路由之前执行,可以用于给用户提示或进行相关操作。
使用路由守卫时,我们可以在createRouter
函数中进行注册,例如:
const routes=[ { path: '/', component: Home }, { path: '/about', component: About, beforeEnter: (to, from, next) => { // 进行路由访问控制或相关操作 } } ]
路由懒加载
路由懒加载是一种将路由组件按需异步加载的方式,只有当路由对应的组件需要使用时,才会动态地加载该组件对应的代码。使用路由懒加载可以优化应用程序的性能
在Vue Router中使用路由懒加载,我们可以通过使用import()
和动态import()
两种方式来实现
使用import()方式实现懒加载
const Home = () => import('./views/Home.vue') const About = () => import('./views/About.vue') const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ] const router = createRouter({ history: createWebHistory(), routes })
使用动态import()方式实现懒加载
const routes = [ { path: '/', component: () => import('./views/Home.vue') }, { path: '/about', component: () => import('./views/About.vue') } ] const router = createRouter({ history: createWebHashHistory(), routes })
使用Vue Router的注意事项
动态参数不能有斜杆:当使用动态参数时,请注意URL不能和动态参数相同。
导航流程:路由类似于栈,每次路由的跳转都会被历史纪录中的历史记录所记录。如果你跳转到相同的路由,那么,历史记录中的最后几次都会被忽略。默认情况下,新跳转的路由不会触发路由更新流程,你需要显式地使用
router.push
或者router.replace
方法来更新到当前路由。导航被取消:如果你在
beforeRouteLeave
或beforeRouteUpdate
守卫中执行了异步操作,则必须确保该异步操作已经完成并调用了next(true)
以确保导航可以进行。
总结
到此这篇关于Vue3中如何使用Vue Router的文章就介绍到这了,更多相关Vue3使用Vue Router内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!