Vue Router 4 是 Vue 的官方路由,适配 Vue3,使用起来也很简单方便。
如果想快速的了解 Vue Router 4 改变了哪些写法,可以参考 从 Vue2 迁移 - Vue Router 。
安装
# npm
npm install vue-router@4
# yarn
yarn add vue-router@4
入门
配置路由
我们先通过 router 4 来创建一个基础的路由,通过 createrouter 方法创建,方式使用 路由懒加载:
// src/routers/index.ts
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
// 引入 RouteRecordRaw 类型以提供内容的校验与提示
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'HomePage',
component: () => import('@/views/Home/HomePage/index.vue'),
meta: {
title: '主页',
},
children: [
{
path: 'list',
name: 'ListPage',
component: () => import('@/views/Home/List/index.vue'),
meta: {
title: '列表页',
},
},
],
},
]
// new Router 变成了 createRouter
const router = createRouter({
// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
history: createWebHashHistory(),
routes,
})
export default router
注册路由
在 main.ts
中注册:
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from '@/routers'
const app = createApp(App)
app.use(router)
app.mount('#app')
搭配 Composition API 使用
在 .vue 文件中使用,更多用法请参考 Vue Router 搭配 组合式API:
import { defineComponent } from 'vue'
import { useRouter, useRoute } from 'vue-router'
export default defineComponent({
name: 'HelloWord',
setup() {
const router = useRouter()
const route = useRoute()
function pushWithQuery(query) {
router.push({
name: 'search',
query: {
...route.query,
},
})
}
},
})
route 是一个响应式对象,他的任何属性都能够被监听,但请避免监听整个 route
:
import { useRoute } from 'vue-router'
export default defineComponent({
setup() {
const route = useRoute()
const userData = ref()
// 当参数更改时获取用户信息
watch(
() => route.params,
async newParams => {
userData.value = await fetchUser(newParams.id)
}
)
},
})
路由匹配
Vue Router 4中,删除了 通配符,因此当你想要 捕获所有的例如 404 页面 时,就得使用正则表达式。更多匹配语法可以参考 路由的匹配语法 :
const routes = [
// 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
// 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
{ path: '/user-:afterUser(.*)', component: UserGeneric },
]
路由元信息 - meta
有时会希望在路由上添加一些额外的信息,例如页面标题等,可以放在 meta 中。
const routes = [
{
path: '/posts',
component: PostsLayout,
children: [
{
path: 'new',
component: PostsNew,
// 只有经过身份验证的用户才能创建帖子
meta: { requiresAuth: true }
}
]
}
]
meta
相关的用法我们之前就很熟悉了,那么如何配置 meta
字段的TypeScript支持呢?
可以通过扩展 RouteMeta
接口:
// typings.d.ts or router.ts
import 'vue-router'
declare module 'vue-router' {
interface RouteMeta {
// 是可选的
isAdmin?: boolean
// 每个路由都必须声明
title: string
}
}
这样配置好之后,声明和使用的地方就都有对应的语法提示和类型校验了:
过渡 / keep-alive
在Router 3中,我们若要给路由加上 keep-alive
或者 transition
的过渡动效时,都是使用用这两个组件来包裹 router-view
组件。
但在Router 4中,这两个组件要被 router-view
所包裹,使用 v-slot API:
<template>
<router-view v-slot="{ Component }">
<transition
name="fade"
mode="out-in"
>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
</template>
导航守卫
导航守卫 在Router 4中也有一部分的变更。主要是 next
参数的变更,它变成了一个 可选的参数 。
全局导航守卫
const router = createRouter({ ... })
router.beforeEach((to, from) => {
// ...
// 返回 false 以取消导航
return false
})
使用 next
:
router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
else next()
})
组件内使用导航守卫
import { defineComponent } from 'vue'
import { onBeforeRouteLeave } from 'vue-router'
export default defineComponent({
name: 'HelloWord',
setup() {
onBeforeRouteLeave(to => {
console.log(to.meta)
})
},
})
更多
要了解更多差异,请访问:从Vue 2迁移 。