Vue Router 4 是 Vue 的官方路由,适配 Vue3,使用起来也很简单方便。
如果想快速的了解 Vue Router 4 改变了哪些写法,可以参考 从 Vue2 迁移 - Vue Router

安装

  1. # npm
  2. npm install vue-router@4
  3. # yarn
  4. yarn add vue-router@4

入门

配置路由

我们先通过 router 4 来创建一个基础的路由,通过 createrouter 方法创建,方式使用 路由懒加载

  1. // src/routers/index.ts
  2. import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
  3. // 引入 RouteRecordRaw 类型以提供内容的校验与提示
  4. const routes: RouteRecordRaw[] = [
  5. {
  6. path: '/',
  7. name: 'HomePage',
  8. component: () => import('@/views/Home/HomePage/index.vue'),
  9. meta: {
  10. title: '主页',
  11. },
  12. children: [
  13. {
  14. path: 'list',
  15. name: 'ListPage',
  16. component: () => import('@/views/Home/List/index.vue'),
  17. meta: {
  18. title: '列表页',
  19. },
  20. },
  21. ],
  22. },
  23. ]
  24. // new Router 变成了 createRouter
  25. const router = createRouter({
  26. // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
  27. history: createWebHashHistory(),
  28. routes,
  29. })
  30. export default router

注册路由

main.ts 中注册:

  1. // src/main.ts
  2. import { createApp } from 'vue'
  3. import App from './App.vue'
  4. import router from '@/routers'
  5. const app = createApp(App)
  6. app.use(router)
  7. app.mount('#app')

搭配 Composition API 使用

在 .vue 文件中使用,更多用法请参考 Vue Router 搭配 组合式API

  1. import { defineComponent } from 'vue'
  2. import { useRouter, useRoute } from 'vue-router'
  3. export default defineComponent({
  4. name: 'HelloWord',
  5. setup() {
  6. const router = useRouter()
  7. const route = useRoute()
  8. function pushWithQuery(query) {
  9. router.push({
  10. name: 'search',
  11. query: {
  12. ...route.query,
  13. },
  14. })
  15. }
  16. },
  17. })

route 是一个响应式对象,他的任何属性都能够被监听,但请避免监听整个 route

  1. import { useRoute } from 'vue-router'
  2. export default defineComponent({
  3. setup() {
  4. const route = useRoute()
  5. const userData = ref()
  6. // 当参数更改时获取用户信息
  7. watch(
  8. () => route.params,
  9. async newParams => {
  10. userData.value = await fetchUser(newParams.id)
  11. }
  12. )
  13. },
  14. })

路由匹配

Vue Router 4中,删除了 通配符,因此当你想要 捕获所有的例如 404 页面 时,就得使用正则表达式。更多匹配语法可以参考 路由的匹配语法

  1. const routes = [
  2. // 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
  3. { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  4. // 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
  5. { path: '/user-:afterUser(.*)', component: UserGeneric },
  6. ]

路由元信息 - meta

有时会希望在路由上添加一些额外的信息,例如页面标题等,可以放在 meta 中。

  1. const routes = [
  2. {
  3. path: '/posts',
  4. component: PostsLayout,
  5. children: [
  6. {
  7. path: 'new',
  8. component: PostsNew,
  9. // 只有经过身份验证的用户才能创建帖子
  10. meta: { requiresAuth: true }
  11. }
  12. ]
  13. }
  14. ]

meta 相关的用法我们之前就很熟悉了,那么如何配置 meta 字段的TypeScript支持呢?
可以通过扩展 RouteMeta 接口:

  1. // typings.d.ts or router.ts
  2. import 'vue-router'
  3. declare module 'vue-router' {
  4. interface RouteMeta {
  5. // 是可选的
  6. isAdmin?: boolean
  7. // 每个路由都必须声明
  8. title: string
  9. }
  10. }

这样配置好之后,声明和使用的地方就都有对应的语法提示和类型校验了:
image.png

过渡 / keep-alive

在Router 3中,我们若要给路由加上 keep-alive 或者 transition 的过渡动效时,都是使用用这两个组件来包裹 router-view 组件。
但在Router 4中,这两个组件要被 router-view 所包裹,使用 v-slot API

  1. <template>
  2. <router-view v-slot="{ Component }">
  3. <transition
  4. name="fade"
  5. mode="out-in"
  6. >
  7. <keep-alive>
  8. <component :is="Component" />
  9. </keep-alive>
  10. </transition>
  11. </router-view>
  12. </template>

导航守卫

导航守卫 在Router 4中也有一部分的变更。主要是 next 参数的变更,它变成了一个 可选的参数

全局导航守卫

  1. const router = createRouter({ ... })
  2. router.beforeEach((to, from) => {
  3. // ...
  4. // 返回 false 以取消导航
  5. return false
  6. })

使用 next

  1. router.beforeEach((to, from, next) => {
  2. if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  3. else next()
  4. })

组件内使用导航守卫

  1. import { defineComponent } from 'vue'
  2. import { onBeforeRouteLeave } from 'vue-router'
  3. export default defineComponent({
  4. name: 'HelloWord',
  5. setup() {
  6. onBeforeRouteLeave(to => {
  7. console.log(to.meta)
  8. })
  9. },
  10. })

更多

要了解更多差异,请访问:从Vue 2迁移