跳至内容

路由元字段

有时,您可能希望将任意信息附加到路由,例如:过渡名称或角色以控制谁可以访问路由等。这可以通过 meta 属性来实现,该属性接受一个属性对象,可以在路由位置和导航守卫中访问。您可以像这样定义 meta 属性

js
const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // only authenticated users can create posts
        meta: { requiresAuth: true },
      },
      {
        path: ':id',
        component: PostsDetail,
        // anybody can read a post
        meta: { requiresAuth: false },
      },
    ],
  },
]

那么我们如何访问这个 meta 字段呢?

首先,routes 配置中的每个路由对象都称为 **路由记录**。路由记录可能是嵌套的。因此,当匹配路由时,它可能匹配多个路由记录。

例如,使用上面的路由配置,URL /posts/new 将匹配父路由记录 (path: '/posts') 和子路由记录 (path: 'new')。

由路由匹配的所有路由记录都暴露在 route 对象上(以及导航守卫中的路由对象)作为 route.matched 数组。我们可以循环遍历该数组以检查所有 meta 字段,但 Vue Router 还为您提供了一个 route.meta,它是从父级到子级的所有 meta 字段的非递归合并。这意味着您可以简单地编写

js
router.beforeEach((to, from) => {
  // instead of having to check every route record with
  // to.matched.some(record => record.meta.requiresAuth)
  if (to.meta.requiresAuth && !auth.isLoggedIn()) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    return {
      path: '/login',
      // save the location we were at to come back later
      query: { redirect: to.fullPath },
    }
  }
})

TypeScript

可以通过扩展 vue-router 中的 RouteMeta 接口来对元字段进行类型化

ts
// This can be directly added to any of your `.ts` files like `router.ts`
// It can also be added to a `.d.ts` file. Make sure it's included in
// project's tsconfig.json "files"
import 'vue-router'

// To ensure it is treated as a module, add at least one `export` statement
export {}

declare module 'vue-router' {
  interface RouteMeta {
    // is optional
    isAdmin?: boolean
    // must be declared by every route
    requiresAuth: boolean
  }
}