import { createRouter, createWebHashHistory } from "vue-router";
import { defineAsyncComponent } from "vue";
import type { Component } from "vue";
import type { RouteRecordRaw } from "vue-router";
import { fallbackUserRoute, userMenu } from "./userMenu";
import type { UserNavItem } from "./types";
const pageComponents: Record<string, Component> = {
profile: defineAsyncComponent(() => import("./pages/ProfilePage.vue")),
security: defineAsyncComponent(() => import("./pages/SecurityPage.vue")),
authorizations: defineAsyncComponent(
() => import("./pages/AuthorizationsPage.vue"),
),
sessions: defineAsyncComponent(() => import("./pages/SessionsPage.vue")),
articles: defineAsyncComponent(() => import("./pages/ArticlesPage.vue")),
mumbles: defineAsyncComponent(() => import("./pages/MumblesPage.vue")),
timelines: defineAsyncComponent(() => import("./pages/TimelinesPage.vue")),
albums: defineAsyncComponent(() => import("./pages/AlbumsPage.vue")),
};
const viewlessComponent: Component = { render: () => null };
const contentEditorChildren: Record<string, RouteRecordRaw[]> = {
articles: [
{ path: "create", name: "articles-create", component: viewlessComponent },
{
path: "edit/:id",
name: "articles-edit",
component: viewlessComponent,
},
],
mumbles: [
{ path: "create", name: "mumbles-create", component: viewlessComponent },
{
path: "edit/:id",
name: "mumbles-edit",
component: viewlessComponent,
},
],
timelines: [
{ path: "create", name: "timelines-create", component: viewlessComponent },
{
path: "edit/:id",
name: "timelines-edit",
component: viewlessComponent,
},
],
albums: [
{ path: "create", name: "albums-create", component: viewlessComponent },
{ path: "edit/:id", name: "albums-edit", component: viewlessComponent },
],
};
function menuRoute(item: UserNavItem): RouteRecordRaw {
return {
path: item.hash.replace(/^#/, ""),
name: item.key,
component: pageComponents[item.key],
meta: {
key: item.key,
icon: item.icon,
title: item.title,
subtitle: item.subtitle,
group: item.group,
accent: item.accent,
},
children: contentEditorChildren[item.key],
};
}
export const userRouter = createRouter({
history: createWebHashHistory(),
routes: [
...userMenu.map(menuRoute),
{ path: "/:pathMatch(.*)*", redirect: `/${fallbackUserRoute.key}` },
],
});
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
代码解释
这是一个 Vue 3 + Vue Router 的路由配置文件,用于构建用户中心相关的路由系统。
核心功能模块
1. 页面组件映射 (pageComponents)
const pageComponents: Record<string, Component> = { ... }
- 使用
defineAsyncComponent实现懒加载,优化首屏加载性能 - 包含 8 个用户中心页面:
- 个人资料 (profile)
- 安全设置 (security)
- 授权管理 (authorizations)
- 会话管理 (sessions)
- 文章 (articles)
- 动态 (mumbles)
- 时间线 (timelines)
- 相册 (albums)
2. 无视图组件 (viewlessComponent)
const viewlessComponent: Component = { render: () => null }
- 渲染空内容的占位组件
- 用于需要路由但不需要独立视图的场景(如弹窗编辑)
3. 内容编辑器子路由 (contentEditorChildren)
为 4 类内容(articles/mumbles/timelines/albums)配置统一的增删改查路由:
- 创建路由:
/create - 编辑路由:
/edit/:id(带动态参数)
使用 viewlessComponent 说明编辑操作可能通过模态框或侧边栏实现,而非独立页面。
4. 路由生成函数 (menuRoute)
function menuRoute(item: UserNavItem): RouteRecordRaw
- 将导航菜单项转换为路由配置
- 自动关联:
- 路径处理:去除 hash 前缀
# - 组件绑定:从
pageComponents匹配 - 元数据传递:保留菜单的 icon/title/subtitle 等信息
- 子路由注入:自动挂载对应的编辑器子路由
- 路径处理:去除 hash 前缀
5. 路由实例创建 (userRouter)
export const userRouter = createRouter({ ... })
- 使用 Hash 模式 (
createWebHashHistory),兼容性更好,无需服务器配置 - 路由配置包括:
- 动态生成的菜单路由(通过
userMenu.map(menuRoute)) - 全局 404 重定向到默认页面 (
fallbackUserRoute)
- 动态生成的菜单路由(通过
技术亮点
- 类型安全:完整的 TypeScript 类型标注
- 按需加载:所有页面组件均异步加载
- 元数据驱动:路由配置完全由导航菜单数据驱动
- 扩展性强:新增内容类型只需在 3 个映射表中添加配置
- 路由守卫友好:meta 中保留完整的菜单信息,方便实现权限控制
典型使用场景
- 用户点击"文章"菜单 → 跳转到
/articles - 点击"新建文章" → 跳转到
/articles/create→ 触发模态框显示编辑器 - 点击"编辑" → 跳转到
/articles/edit/123→ 加载指定文章内容到编辑器
AI 正在分析代码…
评论加载中...