Vue Router 4 是 Vue 的官方路由,适配 Vue3,使用起来也很简单方便。
如果想快速的了解 Vue Router 4 改变了哪些写法,可以参考 从 Vue2 迁移 - Vue Router 。
安装
# npmnpm install vue-router@4# yarnyarn add vue-router@4
入门
配置路由
我们先通过 router 4 来创建一个基础的路由,通过 createrouter 方法创建,方式使用 路由懒加载:
// src/routers/index.tsimport { 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 变成了 createRouterconst router = createRouter({// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。history: createWebHashHistory(),routes,})export default router
注册路由
在 main.ts 中注册:
// src/main.tsimport { 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.tsimport '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 }"><transitionname="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迁移 。
