做前端的,谁的收藏夹里没几个 Admin 模板?
早年间我们用 vue-element-admin,后来进入 Vue 3 时代,Vben Admin 成为了许多开发者的首选。但不少刚接手基于 Vben 项目的同学,初期体验是崩溃的:想改个表格的请求逻辑,发现被 useTable 包裹得严严实实;想加个路由,发现要在好几个字典和权限文件里绕圈圈。
为什么 Vben 要设计得这么“绕”?
因为中后台系统的终局,是与业务复杂度的对抗。当你的系统有 100 个页面、20 个角色、500 个复杂表单时,传统的“一把梭”写法会导致代码瞬间失控。
今天,我们不教你怎么 npm run dev,我们直接拆解 Vben 的三大核心设计哲学。搞懂这些,你不仅能驾驭 Vben,更能把这些架构思维用到自己的项目里。如果你想深入了解更多优秀项目的设计思路,可以关注 云栈社区 的开源实战板块,那里有丰富的源码分析和最佳实践。
架构哲学:Monorepo 与“高内聚低耦合”
在最新的 Vben 架构中,它全面转向了 pnpm + Turborepo 的单仓库(Monorepo)架构。
很多人打开源码,看到 apps、packages 一脸懵逼。为什么要这么拆?
apps/web-antd:这是具体的业务宿主。它只负责长什么样(UI)。
packages/layouts:布局基建,侧边栏、顶栏。
packages/request:网络请求,纯粹的 Axios 封装,不依赖任何 UI 组件。
packages/utils:纯函数工具。
面试官问:“你们的后台模板是如何保证业务代码与底层基建解耦的?”
满分回答:
“我们参考了 Vben 的架构,采用 Monorepo 模式。底层的请求库、通用 Hook、权限路由校验全部抽象到了独立的 Package 中。
这样做的好处是,如果明天公司要求把 UI 库从 Ant Design 换成 Element Plus(或者 Naive UI),我只需要在 apps 里新建一个宿主应用,底层的登录逻辑、权限拦截、API 封装一行代码都不用改,直接复用。”
这就是架构级的“低耦合”。
核心命脉:动态路由与菜单渲染机制
Vben 最复杂的模块,就是权限路由。它支持前端角色控制 (Role) 和后端动态路由 (Back) 两种模式。
我们拆解最企业级的后端动态模式。
在 src/router/guard/permissionGuard.ts 中,藏着它的核心逻辑:
// 简化后的 Vben 路由守卫逻辑
router.beforeEach(async (to, from, next) => {
const token = getToken();
// 1. 没登录?去登录页
if (!token) {
if (whitePathList.includes(to.path)) return next();
return next('/login');
}
const userStore = useUserStore();
const permissionStore = usePermissionStore();
// 2. 已经有用户信息和权限了?直接放行
if (userStore.getUserInfo) {
return next();
}
// 3. 🌟 核心:刚登录/刷新页面,需要拉取权限
try {
// 拿用户信息(含角色名)
await userStore.getUserInfoAction();
// 🌟 从后端接口获取该用户的路由表 (JSON)
// 并在内部将其转换为真实的 Vue Router 对象
const routes = await permissionStore.buildRoutesAction();
// 🌟 动态添加路由
routes.forEach((route) => {
router.addRoute(route);
});
// 4. 路由添加完成后,触发重定向(重要!防止刚 add 的路由找不到)
next({ ...to, replace: true });
} catch (error) {
// 接口挂了或者 Token 失效,清空状态踢回登录
userStore.logout();
next('/login');
}
});
为什么 Vben 的菜单能自动生成?
因为 Vben 在 buildRoutesAction 里,不仅拼装了供 Vue Router 使用的路由树,还顺便抽取了带有 meta.title 和 meta.icon 的信息,生成了一棵菜单树 (Menu Tree)。左侧的菜单栏直接去读这棵树渲染,保证了路由和菜单的绝对统一。
开发范式革命:Schema 驱动的表单与表格
这是 Vben 被吐槽“封装过度”,但也是它最高级的地方。
传统写法(又长又臭):
<template>
<Form :model="formState">
<FormItem label="用户名" name="username">
<Input v-model:value="formState.username" placeholder="请输入" />
</FormItem>
<FormItem label="状态" name="status">
<Select v-model:value="formState.status" :options="statusList" />
</FormItem>
<!-- 这里还有 20 个字段... -->
</Form>
</template>
一旦表单项变多,模板文件会突破几千行。
Vben 的解法:配置化 (Schema-driven)
它封装了强大的 useForm。你不需要写 HTML,你只需要写JSON 配置。
import { useForm } from '@vben/components';
// 🌟 只需要一套配置,搞定渲染、校验、默认值、组件映射
const [registerForm, { validate, getFieldsValue }] = useForm({
schemas: [
{
field: 'username',
component: 'Input',
label: '用户名',
required: true,
componentProps: { placeholder: '请输入用户名' }
},
{
field: 'status',
component: 'Select',
label: '状态',
componentProps: {
options: [ { label: '启用', value: 1 }, { label: '禁用', value: 0 } ]
}
}
],
labelWidth: 100,
showSubmitButton: true,
});
const handleSubmit = async () => {
// 一键校验并拿值,毫无心智负担
const values = await validate();
console.log(values);
};
这有什么好处?
- 极度清爽:HTML 模板几乎消失。
- 动态渲染:如果表单是后端动态下发的(低代码),Schema 模式可以直接接入,传统写法根本做不到。
- 高度复用:表单的 Schema 可以抽离成单独的
xxx.data.ts 文件,甚至可以和表格(Table)的列配置共享字典。
Vben 到底适合什么样的团队?
总结一下,不要盲目跟风。
- 不要用 Vben 如果:你的项目只有 5 个页面,全是简单的展示。用 Vben 就像开着航母去买菜,光是编译速度和包体积就让你崩溃。
- 必须用 Vben 如果:你开发的是大型 ERP、CRM 或者是需要高度动态化的企业级中台。它的基建(国际化、权限、主题、动态表单)会帮你省去至少3 个月的底层研发时间。
结语
阅读优秀的开源项目源码,是前端进阶的最快捷径。Vben Admin 能够爆火,正是因为它踩遍了中后台开发的所有的坑,并给出了一套“虽然有些重,但绝对标准”的解法。
当你觉得它封装得“太深”时,不妨往回走一步,想想它为什么要这么设计。如果你想系统性地学习这类框架的设计精髓,可以参考我们整理的 Vben Admin 技术文档解析。
在这个周末,拉下它的源码,顺着 main.ts 走一遍,你对 Vue 3 的理解绝对会升华。
周末愉快,樱花开了,别忘了出门走走!🌸