Vue Router是一个官方的Vue.js路由管理器,它与 Vue.js 核心深度集成,通过它可以轻松地为单页应用程序(SPA)提供路由管理和导航功能。今天我们就来聊一聊Vue 3中使用Vue Router的那些事儿。
安装和配置Vue Router
安装Vue Router
安装Vue Router只需要在vue项目中打开终端,输入如下命令即可安装:
npm 方式安装
代码语言:javascript复制npm install vue-router@4
yarn方式安装
代码语言:javascript复制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组件中代码
代码语言:javascript复制<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组件中代码
代码语言:javascript复制<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对象时,其为我们提供了很多配置项,带完整配置项的示例代码如下:
代码语言:javascript复制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还支持使用可选的参数和正则表达式来定义路由。例如,可以这样定义一个包含可选参数的动态路由:
代码语言:javascript复制{
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
: 在路由跳转完成后执行,可以用于对页面进行一些操作,例如监测页面埋点或修改页面标题等。
一个验证用户是否登录的路由守卫示例代码如下
代码语言:javascript复制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()方式实现懒加载
代码语言:javascript复制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()方式实现懒加载
代码语言:javascript复制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)
以确保导航可以进行。
OK,关于vue3中使用Vue Router的相关内容就聊到这里,有问题的小伙伴评论区留言,喜欢的小伙伴点赞关注加收藏哦!!