拒绝过度封装!GoWind Admin:基于Element Plus重塑中后台CRUD开发范式
来源: 掘金前端本周最热
拒绝过度封装!GoWind Admin:基于Element Plus重塑中后台CRUD开发范式
前言:为什么越来越多人厌倦传统Admin脚手架?
在 Golang + Vue 中后台开发领域,成熟一体化脚手架早已成为企业项目开发的首选方案。标准化脚手架能够完成项目初始化、权限封装、基础页面搭建等重复性工作,大幅提升项目落地速度。但在实际业务迭代过程中,不少开发者都会遇到同一个普遍性痛点:部分脚手架过度封装底层组件,固化编码范式,变相约束开发者的编码自由度。
这类脚手架为了统一团队编码规范、降低入门门槛,对页面布局、请求逻辑、弹窗交互、表格渲染等底层能力做深层次封装。该方案对简单标准化CRUD页面十分友好,但适配复杂企业级业务时,弊端会逐步凸显:
-
定制改造成本高:非标准布局、特殊表格交互、定制化弹窗逻辑,无法通过简单配置实现,需要深入破解上层封装、重写底层内部方法;
-
黑盒问题难以排查:底层逻辑完全封闭,开发者无法感知内部运行机制,线上渲染异常、状态联动报错等问题排查难度大幅增加;
-
编码范式强制绑定:项目强依赖框架私有API与定制组件,开发者必须适配框架固定写法,无法根据团队技术习惯自由调整;
-
进阶学习成本偏高:基础上手简单,但深度定制门槛高,开发者除UI框架基础语法外,还需要熟记框架大量私有配置项与内部规则。
基于此,**GoWind Admin(风行)**脚手架针对行业痛点,重构了中后台页面开发逻辑。依托原生Element Plus,自研一套渐进式Pro业务组件库,摒弃过度封装思维,打造「配置优先、自由兜底、层级可选」的全新CRUD开发模式,从根源解决传统脚手架的束缚问题。
本文将从技术底层、设计理念、分层用法、落地价值四个维度,深度拆解这套适配企业级项目的开发方案。
一、GoWind Admin 整体技术底座
GoWind Admin(风行)是一款开箱即用的前后端一体化企业级脚手架,后端基于Golang微服务框架go-kratos开发,完美支持单体/微服务双模式部署,适配从小型团队单体项目到中大型企业微服务集群各类场景;为适配不同技术栈偏好、不同团队选型需求,前端内置三套完整且独立的版本,覆盖主流中后台技术方案:
-
Vue3 Vben版:基于Vue3 + TypeScript + Vite + Ant Design Vue打造,适配习惯配置化高阶封装、追求极速开发的团队;
-
Vue3 Element Plus版:轻量化纯净版本,依托原生Element Plus开发,低侵入无黑盒封装,兼顾效率与自由度,也是本文核心讲解版本;
-
React版:基于React19 + TypeScript + Ant Design V6,无UMI框架绑定,轻量化架构,适配React技术栈开发团队。
本次重点解析的Vue3 Element Plus版,主打轻量化、低侵入、无黑盒封装,核心技术栈如下:
-
基础框架:Vue3 + TypeScript + Vite(原生语法,无额外语法糖)
-
UI底座:Element Plus(100%原生组件,无二次深层封装)
-
表格双引擎:内置vxe-table/原生el-table,一键自由切换
-
状态管理:TanStack Vue Store(轻量化全局状态,替代冗余Pinia模块)
区别于其他脚手架,该版本最大核心亮点:所有Pro业务组件均基于原生Element Plus原子组件封装,不隐藏底层API,所有Props、事件、插槽完全对外开放。开发者随时可以放弃配置化写法,回归原生Element Plus编码。
二、Pro组件库核心设计理念:渐进式开发
市面上绝大多数配置化组件库只有两种极端模式:要么纯模板编写(重复冗余代码),要么全配置化(高度封装、无法定制)。GoWind Pro组件库打破二元对立,提出四级渐进式开发模型,让开发者根据业务复杂度,自由选择编码层级,适配100%中后台业务场景。
核心设计思想:用一份配置对象,描述完整CRUD页面生命周期(搜索-工具栏-表格-分页-弹窗);配置解决标准化场景,插槽/原生组件兜底复杂场景。
组件库整体目录结构清晰,职责单一,无无效冗余模块:
Pro/
├── ProForm/ # 动态配置化表单
├── ProSearch/ # 自适应搜索栏
├── ProToolbar/ # 页面工具栏
├── ProTable/ # 双引擎自适应表格
├── ProPagination/ # 智能分页组件
├── ProModal/ # 弹窗/抽屉通用组件
├── ProPage/ # 一站式页面编排入口
├── composables/ # 可复用状态hooks
├── constants/ # 全局默认常量
└── index.ts # 统一导出入口
三、四级开发层级:按需选型,拒绝强制绑定
我们将页面开发划分为四个层级,从低代码配置到原生原子组件自由组合,层层递进,覆盖简单/常规/复杂/定制化四类业务页面,下面结合实际业务场景逐一讲解。
Level 1:ProPage 零模板配置(标准CRUD场景)
适用场景:租户管理、用户管理、字典管理、菜单管理等90%标准化后台页面
核心逻辑:仅通过一份ProPageConfig配置对象,自动生成搜索栏、工具栏、数据表格、新增/编辑弹窗、分页组件,全程无需编写任何模板代码,纯声明式开发。
相较于传统固化模板的开发模式,该方案能减少70%以上重复模板代码,同时所有配置字段均有完善TS类型提示,规避拼写错误、参数不匹配等问题。下面给出一份完整版可直接上线的租户管理页面,包含搜索、标签状态、时间格式化、操作按钮、新增/编辑抽屉全套能力:
<template>
<!-- 一行标签,完成完整CRUD页面:搜索+表格+分页+弹窗 -->
<ProPage :config="pageConfig" />
</template>
<script setup lang="ts">
import { ProPage, type ProPageConfig } from "@/components/Pro";
// 项目内置统一请求封装
import { fetchListTenants, createTenant, updateTenant, useDeleteTenant } from "@/api/composables";
// 删除接口
const { mutateAsync: deleteTenant } = useDeleteTenant();
const pageConfig: ProPageConfig = {
// 切换表格引擎:vxe / element
engine: "element",
// 搜索区域配置
search: {
grid: true,
showNumber: 4,
fields: [
{
type: "input",
label: "租户名称",
field: "name",
attrs: { clearable: true, placeholder: "请输入租户名称" }
},
{
type: "input",
label: "租户编码",
field: "code",
attrs: { clearable: true }
},
{
type: "select",
label: "状态",
field: "status",
attrs: { clearable: true },
options: [
{ label: "启用", value: 1 },
{ label: "禁用", value: 0 }
]
},
{
type: "date-picker",
label: "创建时间",
field: "createdAt",
attrs: { type: "daterange", rangeSeparator: "~" }
}
]
},
// 表格核心配置
table: {
// 数据源请求
listAction: async (query) => {
const { page, pageSize, ...params } = query;
const res = await fetchListTenants({ page, pageSize, ...params });
return { items: res.items || [], total: res.total || 0 };
},
// 单行删除
deleteAction: async (ids) => await deleteTenant({ id: ids as number }),
// 左侧工具栏
toolbar: ["add", "delete"],
// 右侧默认工具:刷新、列筛选
defaultToolbar: ["refresh", "filter"],
columns: [
{ type: "selection", label: "", width: 50 },
{ type: "index", label: "序号", width: 60 },
{ prop: "name", label: "租户名称", minWidth: 140 },
{ prop: "code", label: "租户编码", minWidth: 120 },
// 内置 cellType:tag 自动渲染状态标签,无需插槽
{
prop: "status",
label: "状态",
width: 100,
cellType: "tag",
labelMap: { 1: "启用", 0: "禁用" },
tagType: { 1: "success", 0: "danger" }
},
// 内置日期格式化
{
prop: "createdAt",
label: "创建时间",
minWidth: 180,
cellType: "date",
dateFormat: "YYYY-MM-DD HH:mm:ss"
},
// 全自动操作列
{
prop: "action",
label: "操作",
fixed: "right",
width: 180,
cellType: "tool",
buttons: [
{ name: "edit", text: "编辑" },
{ name: "delete", text: "删除", attrs: { type: "danger" } }
]
}
]
},
// 内置新增/编辑抽屉弹窗(开箱即用)
modal: {
component: "drawer",
drawer: { title: "租户维护", size: "520px" },
fields: [
{ type: "input", label: "租户名称", field: "name", rules: [{ required: true, message: "请输入租户名称" }] },
{ type: "input", label: "租户编码", field: "code", rules: [{ required: true, message: "请输入租户编码" }] },
{ type: "switch", label: "启用状态", field: "status" },
{ type: "textarea", label: "备注", field: "remark", attrs: { rows: 4 } }
],
submitAction: async (data, mode) => {
if (mode === "add") {
await createTenant(data);
} else {
await updateTenant(data);
}
}
}
};
</script>
Level 2:useProPage 命令式控制(外部联动场景)
适用场景:左侧组织树+右侧表格、Tab切换联动、定时器刷新、跨组件通信等需要外部控制页面的场景
传统脚手架中,开发者只能通过ref绑定组件,再调用内部方法,不仅写法冗余,还容易出现挂载时序报错问题。
GoWind 提供 useProPage 组合式函数,抛弃ref绑定组件的传统写法,以命令式API统一管理页面状态、表格刷新、弹窗开关、查询参数。该方案非常适合左侧组织树+右侧表格、Tab联动、按钮刷新等联动场景,下方为可直接复用的「树+表格」完整实战代码:
<template>
<div class="flex gap-4 h-full">
<!-- 左侧部门树 -->
<el-card class="w-64 shrink-0" shadow="never">
<el-tree :data="deptTree" node-key="id" @node-click="handleNodeClick" />
</el-card>
<!-- 右侧ProPage表格 -->
<div class="flex-1 min-w-0">
<Page />
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { ElCard, ElTree } from "element-plus";
import { useProPage, type ProPageConfig } from "@/components/Pro";
import { fetchUserList } from "@/api/composables";
const deptTree = ref([]);
// 1. 通过 useProPage 创建页面组件与全局API
const [Page, pageApi] = useProPage({
search: {
fields: [
{ type: "input", label: "账号", field: "username" },
{ type: "input", label: "昵称", field: "nickname" }
]
},
table: {
listAction: async (params) => {
const res = await fetchUserList(params);
return { items: res.items || [], total: res.total || 0 };
},
columns: [
{ type: "index", label: "序号", width: 60 },
{ prop: "username", label: "账号", minWidth: 120 },
{ prop: "nickname", label: "昵称", minWidth: 120 },
{ prop: "createdAt", label: "创建时间", cellType: "date" }
]
}
});
// 2. 树节点点击,命令式追加部门ID并重载第一页
function handleNodeClick(node: any) {
// reload:重置页码+追加参数,最适合侧边栏联动
pageApi.reload({ deptId: node.id });
}
// 3. 常用API汇总(业务高频)
const handleRefresh = () => pageApi.refresh(); // 刷新当前页
const openAddUser = () => pageApi.openAdd(); // 打开新增弹窗
const getSelectedIds = () => pageApi.getSelectionIds(); // 获取选中ID
</script>
Level 3:插槽定制化(复杂单元格/交互场景)
适用场景:单元格自定义渲染(Switch、图标、渐变标签)、工具栏拓展按钮、自定义弹窗、行内特殊交互
配置化无法覆盖高度个性化单元格,例如状态开关、彩色标签、操作权限按钮等场景。ProPage 支持配置为主、插槽补强的混合写法,所有列、工具栏、弹窗都支持插槽重写。下面示例展示:自定义Tag、Switch开关、展开行详情、工具栏拓展按钮四类高频用法:
<template>
<ProPage :config="pageConfig" @edit="handleEdit">
<!-- 自定义状态标签插槽 -->
<template #status="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" size="small">
{{ scope.row.status === 1 ? "正常" : "停用" }}
</el-tag>
</template>
<!-- 行内开关插槽,直接修改状态 -->
<template #switchStatus="scope">
<el-switch v-model="scope.row.status" @change="handleSwitchChange(scope.row)" />
</template>
<!-- 工具栏左侧拓展插槽 -->
<template #toolbar-left>
<el-button type="warning" plain @click="batchExport">批量导出</el-button>
</template>
</ProPage>
</template>
<script setup lang="ts">
import { ProPage, type ProPageConfig } from "@/components/Pro";
import { ElTag, ElSwitch, ElButton } from "element-plus";
import { updateUserStatus } from "@/api/composables";
const pageConfig: ProPageConfig = {
table: {
toolbar: ["add"],
columns: [
{ type: "index", label: "序号", width: 60 },
{ prop: "username", label: "账号", minWidth: 120 },
// 绑定自定义插槽
{ prop: "status", label: "账号状态", width: 120, slotName: "status" },
{ prop: "status", label: "快速开关", width: 120, slotName: "switchStatus" },
{ prop: "createdAt", label: "创建时间", cellType: "date" }
]
}
};
// 行内开关回调
async function handleSwitchChange(row: any, val: number) {
await updateUserStatus({ id: row.id, status: val });
}
function handleEdit(row: any) {}
function batchExport() {}
</script>
Level 4:原子组件自由组合(非标准布局场景)
适用场景:完全非标准页面、多表格嵌套、多搜索栏联动、特殊异形布局等极端复杂业务
这也是本框架区别于重度封装脚手架的核心亮点:当业务极度特殊、ProPage编排层无法满足布局时,你可以直接放弃顶层封装,单独导入 ProSearch / ProTable / ProToolbar / ProModal 原子组件,自由拼装页面。下方为「独立原子组件」最简示例,完整还原底层组装逻辑:
<template>
<div class="custom-page p-4">
<!-- 独立搜索栏 -->
<ProSearch :fields="searchFields" grid @search="onSearch" @reset="onReset"/>
<ProToolbar left-buttons="['add']" @button-click="onToolbarClick" class="mt-4"/>
<!-- 完全自主控制表格 -->
<ProTable
class="mt-4"
:columns="columns"
:data="tableState.data.value"
:loading="tableState.loading.value"
:total="tableState.pagination.total"
v-model:current-page="tableState.pagination.currentPage"
v-model:page-size="tableState.pagination.pageSize"
@selection-change="tableState.handleSelectionChange"
/>
</div>
</template>
<script setup lang="ts">
import { reactive } from "vue";
import { ProSearch, ProTable, ProToolbar, useTableState } from "@/components/Pro";
import { fetchUserList } from "@/api/composables";
// 1. 搜索字段
const searchFields = [
{ type: "input", label: "账号", field: "username" }
];
const query = reactive<Record<string, any>>({});
// 2. 表格状态托管
const tableState = useTableState({
indexAction: async (params) => await fetchUserList(params)
});
// 3. 表格列
const columns = [
{ type: "selection", width: 50 },
{ type: "index", label: "序号", width: 60 },
{ prop: "username", label: "账号", minWidth: 120 }
];
function onSearch(params: any) {
Object.assign(query, params);
tableState.fetch(query, true);
}
function onReset() {}
function onToolbarClick(name: string) {}
</script>
四、双表格引擎:一键切换,适配不同团队习惯
表格是中后台系统的核心组件,ProTable内置双渲染引擎,一行配置即可切换,无需修改业务代码:
-
vxe-table(默认):功能完整版,支持虚拟滚动、树形表格、行内编辑、批量导出,适配大数据量复杂表格;
-
el-table:Element Plus原生表格,轻量无额外依赖,适配中小型数据页面,降低项目打包体积。
框架内部已完成两套引擎的API自动映射,开发者无需适配差异化语法,仅需修改engine参数即可完成切换,大幅降低团队适配成本。
五、GoWind Admin 整体核心优势总结
1. 弱化封装理念,全权掌控代码逻辑
区别于深层封装的脚手架,Vue3 Element Plus版本采用弱封装设计理念,所有Pro业务组件均基于原生UI组件二次轻量化封装,底层API、组件Props、事件、插槽全部对外开放。开发者可自由切换配置化/原生编码模式,拥有100%代码控制权。
2. 降低进阶学习成本
无需记忆框架私有语法、私有组件属性,开发者仅需掌握Vue3+Element Plus原生知识即可上手;配置化语法贴合原生组件设计逻辑,零基础开发者1小时即可熟练使用。
3. 层级化适配全业务场景
摒弃“一刀切”开发模式,标准化页面用Level1零模板开发,复杂联动页面用Level2命令式控制,定制化页面用Level3/4插槽/原生组合,适配从简单CRUD到复杂异形页面的所有场景。
4. 前后端一体化协同
后端基于go-kratos微服务架构,内置完整的租户、权限、菜单、任务调度、日志管理等企业级能力;前端Pro组件字段结构、请求格式与后端接口完美适配,无需额外做数据适配,一站式完成项目开发。
六、写在最后
优质的中后台脚手架,核心定位应当是赋能开发者,而非限制开发者。
市面上多数脚手架仅解决项目“从0到1”的初始化问题,固化的编码模式却会限制项目长期迭代;GoWind Admin 通过四级渐进式开发模型,完美平衡开发效率与编码自由度,既能满足标准化页面低代码开发需求,也能支撑复杂定制化业务的原生编码开发。同时多版本前端架构,可全方位适配不同技术栈团队的选型需求。
如果你早已厌倦被框架束缚、反复破解深层封装,追求轻量化、透明化、高自由度的中后台开发体验,不妨尝试 GoWind Admin。
附:项目相关地址
- Github地址:github.com/tx7do/go-wi…
- Gitee地址:gitee.com/tx7do/go-wi…
- 在线演示地址:demo.admin.gowind.cloud
- 默认账号密码:admin / admin