vue-router - 路由元数据

245 阅读1分钟

在Vue的路由系统中,可以在定义路由时,在路由配置对象中添加一个名为meta的属性,用于存储路由元数据

通过meta属性可以在路由对象上附加一些额外的信息,比如过渡名称、路由访问权限等

meta属性可以存储任意类型的值,例如字符串、对象、函数等

当我们在路由配置对象中添加了meta属性后,就可以$route 对象 还有 在导航守卫中的路由对象 访问这些元数据

const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // 开启鉴权
        meta: { requiresAuth: true }
      },
      {
        path: ':id',
        component: PostsDetail
        // 关闭鉴权
        meta: { requiresAuth: false }
      }
    ]
  }
]

routes 配置中的每个路由对象为 路由记录,因为路由记录可以是嵌套的,因此,当一个路由匹配成功后,它可能匹配多个路由记录

一个路由匹配到的所有路由记录会暴露为 $route 对象 还有在导航守卫中的路由对象 的$route.matched 数组中

我们需要遍历这个数组来检查路由记录中的 meta 字段

const routes = [
  {
    path: '/',
    component: Home,
    children: [
      {
        path: 'about',
        component: About,
        children: [
          {
            path: 'contact',
            component: Contact,
            meta: { requiresAuth: true }
          }
        ]
      },
      {
        path: 'dashboard',
        component: Dashboard,
        meta: { auth: 'admin' }
      }
    ]
  }
]

如果访问/about/contact, $route.matched 数组对应的值为

[
  {
    path: '/',
    component: Home
  },
  {
    path: 'about',  
    component: About
  },
  {
    path: 'contact',
    component: Contact,
    meta: { requiresAuth: true }  
  }
]

Vue Router 还提供了一个 $route.meta 对象,它是一个非递归合并所有 meta 字段的对象

import { useRoute } from 'vue-router'

const routes = [
  {
    path: '/',
    component: Home,
    meta: {
      requiresAuth: true
    },
    children: [
      {
        path: 'about',
        component: About,
        meta: {
          requiresAuth: false,
          role: 'user'
        }
      }
    ]
  }
]

// 假设当前匹配的路由地址是 /about
const route = useRoute()
console.log(route.meta) 
/* 
	=> 
	{
		 // 子路由meta会覆盖父路由meta对应的同名属性
		 requiresAuth: false,
     role: 'user'
	}
*/

类型注解

可以通过扩展 RouteMeta 接口来输入 meta 字段:

// typings.d.ts or router.ts 
//   --- .d.ts文件的主要作用就是为第三方库或模块提供类型声明或者类型扩展

// import 'vue-router'告诉typescript这个类型文件是专门用于对vue-router这个库进行类型声明或类型扩展
import 'vue-router'

// 对模块进行类型定义
declare module 'vue-router' {
 	// 之前已经有RouteMeta属性了,多个接口属性之间的类型定义会合并
  interface RouteMeta {
    // 是可选的
    isAdmin?: boolean
    // 每个路由都必须声明
    requiresAuth: boolean
  }
}