在 Vue 3 中,RouteRecord 是构建路由系统的基石,它定义了路由路径、组件、元信息等关键配置。下面我为你完整解析 RouteRecord 的定义、使用场景和高级用法。
一、RouteRecord 是什么?
RouteRecord 是 Vue Router 4 中的核心接口,它定义了:
typescript
interface RouteRecordRaw {
path: string
name?: string
component?: Component
meta?: Record<string, any>
children?: RouteRecordRaw[]
// ... 其他属性
}
二、RouteRecordRaw 完整属性表
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
path |
string |
✅ | 路由路径 |
name |
string |
❌ | 路由名称(命名路由) |
component |
Component |
❌ | 组件(与 components 二选一) |
components |
Record<string, Component> |
❌ | 命名视图组件 |
redirect |
`string | RouteLocation` | ❌ |
alias |
`string | string[]` | ❌ |
children |
RouteRecordRaw[] |
❌ | 子路由 |
meta |
Record<string, any> |
❌ | 元信息(权限控制用) |
beforeEnter |
NavigationGuard |
❌ | 路由独享守卫 |
props |
`boolean | Record<string, any> | (route) => any` |
三、✅ 基础 RouteRecord 定义
1️⃣ 最简单的路由记录
typescript
import { RouteRecordRaw } from 'vue-router'
import HomeView from '@/views/HomeView.vue'
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'home',
component: HomeView
}
]
2️⃣ 命名路由 + 参数
typescript
{
path: '/user/:id',
name: 'user',
component: () => import('@/views/UserView.vue'),
props: true // 将 params.id 作为组件的 props
}
四、✅ 子路由(嵌套路由)
typescript
{
path: '/dashboard',
component: () => import('@/layout/DashboardLayout.vue'),
children: [
{
path: '', // 默认子路由
name: 'dashboard',
component: () => import('@/views/dashboard/Index.vue')
},
{
path: 'profile',
name: 'dashboard.profile',
component: () => import('@/views/dashboard/Profile.vue')
}
]
}
五、✅ 元信息(meta)详解
meta 字段是 权限控制、面包屑、缓存控制 的核心。
typescript
{
path: '/admin',
name: 'admin',
component: () => import('@/views/Admin.vue'),
meta: {
// 权限控制
requiresAuth: true,
roles: ['admin', 'super_admin'],
// 页面标题
title: '管理后台',
// 缓存控制
keepAlive: true,
// 面包屑
breadcrumb: [
{ title: '首页', path: '/' },
{ title: '管理' }
],
// 图标
icon: 'el-icon-settings',
// 排序
order: 1
}
}
六、✅ 在路由守卫中使用 meta
typescript
router.beforeEach((to, from) => {
const token = localStorage.getItem('token')
// 检查是否需要登录
if (to.meta.requiresAuth && !token) {
return { name: 'login' }
}
// 检查角色权限
if (to.meta.roles) {
const userRole = getUserRole()
if (!to.meta.roles.includes(userRole)) {
return { name: 'forbidden' }
}
}
// 设置页面标题
if (to.meta.title) {
document.title = to.meta.title
}
})
七、✅ 动态路由(后端返回菜单)
场景:后端返回 → 前端动态添加路由
typescript
// 后端返回的数据结构示例
const menuData = [
{
path: '/system',
component: 'Layout',
meta: { title: '系统管理', icon: 'system' },
children: [
{
path: 'user',
component: 'User',
meta: { title: '用户管理' }
}
]
}
]
// 转换函数
function transformRoutes(menuList: any[]): RouteRecordRaw[] {
return menuList.map(item => ({
path: item.path,
name: item.name,
// 动态导入组件
component: item.component === 'Layout'
? () => import('@/layout/index.vue')
: () => import(`@/views/${item.component}.vue`),
meta: item.meta,
children: item.children ? transformRoutes(item.children) : []
}))
}
// 动态添加路由
const dynamicRoutes = transformRoutes(menuData)
dynamicRoutes.forEach(route => {
router.addRoute(route)
})
八、✅ 路由记录的高级用法
1️⃣ 命名视图(多组件布局)
typescript
{
path: '/settings',
components: {
default: () => import('@/views/Settings.vue'), // 默认视图
sidebar: () => import('@/components/Sidebar.vue'), // 命名视图
header: () => import('@/components/Header.vue')
}
}
模板中使用:
vue
<router-view />
<router-view name="sidebar" />
<router-view name="header" />
2️⃣ 重定向
typescript
{
path: '/home',
redirect: '/dashboard' // 简单重定向
}
{
path: '/old/:id',
redirect: to => ({ // 函数重定向
path: '/new/:id',
query: { from: to.fullPath }
})
}
3️⃣ 路由别名
typescript
{
path: '/user',
alias: '/member', // 访问 /member 和 /user 一样
component: UserView
}
九、✅ TypeScript 类型增强
typescript
// types/router.d.ts
import 'vue-router'
declare module 'vue-router' {
interface RouteMeta {
// 权限相关
requiresAuth?: boolean
roles?: string[]
// 页面信息
title?: string
icon?: string
order?: number
// 缓存控制
keepAlive?: boolean
// 自定义字段
[key: string]: any
}
}
十、✅ 企业级路由配置示例
typescript
// router/routes.ts
import { RouteRecordRaw } from 'vue-router'
import Layout from '@/layout/index.vue'
export const constantRoutes: RouteRecordRaw[] = [
{
path: '/login',
name: 'login',
component: () => import('@/views/login/index.vue'),
meta: { hidden: true }
},
{
path: '/404',
name: '404',
component: () => import('@/views/error/404.vue'),
meta: { hidden: true }
}
]
export const asyncRoutes: RouteRecordRaw[] = [
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
component: () => import('@/views/dashboard/index.vue'),
name: 'Dashboard',
meta: { title: '控制台', icon: 'dashboard', affix: true }
}
]
},
{
path: '/system',
component: Layout,
meta: { title: '系统管理', icon: 'system', roles: ['admin'] },
children: [
{
path: 'user',
component: () => import('@/views/system/user/index.vue'),
name: 'User',
meta: { title: '用户管理', icon: 'user' }
}
]
}
]
// 404 页面必须放在最后
export const notFoundRoute: RouteRecordRaw = {
path: '/:pathMatch(.*)*',
redirect: '/404',
meta: { hidden: true }
}
十一、✅ RouteRecord 的实用工具函数
typescript
// 获取所有路由记录(扁平化)
function getFlatRoutes(routes: RouteRecordRaw[]): RouteRecordRaw[] {
return routes.reduce((prev, curr) => {
prev.push(curr)
if (curr.children) {
prev.push(...getFlatRoutes(curr.children))
}
return prev
}, [] as RouteRecordRaw[])
}
// 根据路径查找路由记录
function findRouteByPath(path: string, routes: RouteRecordRaw[]): RouteRecordRaw | null {
for (const route of routes) {
if (route.path === path) return route
if (route.children) {
const found = findRouteByPath(path, route.children)
if (found) return found
}
}
return null
}
十二、✅ 常见问题
❌ 1. 动态导入路径错误
typescript
// ❌ 错误
component: () => import(`@/views/${component}.vue`)
// ✅ 正确(需配置 Vite 动态导入)
component: () => import(/* @vite-ignore */ `@/views/${component}.vue`)
❌ 2. 子路由 path 不以 / 开头
typescript
// ❌ 错误
children: [{ path: '/profile' }]
// ✅ 正确
children: [{ path: 'profile' }]
十三、✅ 一句话总结
✅ RouteRecord 是 Vue Router 的"配置单元"
✅ 核心是:path + component + meta
✅ meta 承载了权限、面包屑、缓存等业务逻辑
✅ 动态路由 = 后端返回 + addRoute
如果你愿意,我可以下一步帮你:
- ✅ 实现完整的动态路由 + 权限控制系统
- ✅ 配置Vite 支持动态导入的别名
- ✅ 搭建企业级后台管理系统路由架构
你现在是自己搭建后台系统 还是维护现有项目?