很多兄弟在使用 Vue3 了,但对 Vue3 的路由却了解的非常少。甚至只知道基本的跳转和参数获取,这样做一些稍微复杂的功能肯定不够用的。最近就把 Vue3 的路由(Vue-Router4)的版本差异和使用场景整理了一下分享给大家。会的兄弟可以复习一下,不会的兄弟抓紧学起来哦!
路由模式
Vue3 中不再使用 new Router()
创建 router ,而是调用 createRouter
方法:
import {
createRouter } from 'vue-router'
const router = createRouter({
// ...
})
路由模式 mode
配置改为 history
,属性值调整为:
"history"
=>createWebHistory()
"hash"
=>createWebHashHistory()
"abstract"
=>createMemoryHistory()
import {
createRouter, createWebHistory } from 'vue-router'
// createWebHashHistory 和 createMemoryHistory (SSR相关) 同理
createRouter({
history: createWebHistory(),
routes: []
})
基础路径 base
被作为 createWebHistory
的第一个参数进行传递(其他路由模式也是一样):
import {
createRouter, createWebHistory } from 'vue-router'
createRouter({
history: createWebHistory('/base-url/'),
routes: []
})
路由跳转
使用组件跳转,方式还是和 Vue2 一样:
<RouterLink to="/user">User</RouterLink>
<RouterLink :to="{ path: '/user', query: { username: 'Jack' } }">User</RouterLink>
<RouterLink :to="{ name: 'user', params: { username: 'Tom' } }">User</RouterLink>
当然,最常见的还是编程式导航,这时候需要引入 useRouter
方法:
import {
useRouter } from 'vue-router'
const router = useRouter()
// 字符串路径
router.push('/user')
// 带有路径的对象
router.push({
path: '/user', query: {
username: 'Jack' } })
router.push({
path: '/user', hash: '#team' })
// 带有命名的对象
router.push({
name: 'user', query: {
username: 'Jack' } })
router.push({
name: 'user', params: {
username: 'Tom' } })
router.push({
name: 'user', hash: '#team' })
注意:参数 params
不能和 path
一起使用。RouterLink 组件 to
属性与 router.push()
接受的参数相同,两者的规则也完全相同。
导航守卫
全局前置守卫
全局前置守卫通常用来做权限控制,使用 router.beforeEach
即可添加:
const router = createRouter({
... })
router.beforeEach((to, from) => {
// ...
// 返回 false 以取消导航
return false
})
每个守卫方法接收两个参数:
to
:即将进入的目标路由from
:当前正要离开的路由
可以返回的值如下:
false
:取消当前的导航。true
或undefined
,调用下一个守卫。- 一个路由地址:字符串或对象。表示中断当前导航,进行一个新的导航。
router.beforeEach(async (to, from) => {
// 检查用户是否已登录,并且避免无限重定向
if (!isAuthenticated && to.name !== 'Login') {
return {
name: 'Login' } // 将用户重定向到登录页面
}
})
在之前的 Vue Router 版本中,也是可以使用第三个参数 next
的。目前,它仍然是被支持的,这意味着你可以向任何导航守卫传递第三个参数。在这种情况下,要确保 next
在导航守卫中只被调用一次。
全局解析守卫
router.beforeResolve
用法和 router.beforeEach
类似。它是在导航被确认之前,所有组件内守卫和异步路由组件被解析之后被调用。下面这个例子,确保用户可以访