先说说我为什么造这个轮子。
之前写 React 的时候,我最喜欢的就是 antd 的 ProComponents:
ProTable一份列 schema 下去,搜索栏、表格、分页、工具栏全出来了,ProForm的联动和弹窗表单也是拿来就用。那段时间写中后台是真的爽——业务代码只写业务,模板代码一行不用重复。后来换了技术栈,改用 Vue3 + Element Plus。习惯性的想找同款,然后把 npm 翻了个遍:要么是几年没维护的老仓库,要么功能只覆盖一小块(有表格没表单、有表单没布局),要么 API 设计和 ProComponents 完全对不上,用起来处处别扭。用惯了好工具,再回去手写
el-form+el-table的复读机代码,是真的难受。所以干脆自己动手:参照 ProComponents 的 API 心智,给 Element Plus 封装了一套 el-pro-components。React 那边验证过的设计,搬到 Vue 这边,少踩坑。今天正式发版,开源出来给同样从 React 转 Vue、或者单纯想省 CRUD 工作量的同学用。
- 📖 文档站:april-zheng.github.io/el-pro-comp…(在线示例 + 全组件 API 文档)
- 📦 npm:el-pro-components
- 🐙 GitHub:April-Zheng/el-pro-components(求个 Star ⭐)
- 📄 License:MIT | 当前版本
0.1.0| peer:vue@^3.3+element-plus@^2.8
一句话介绍
列 schema 驱动的中后台模板组件库:ProTable / ProForm / ProDescriptions / ProLayout / 弹窗抽屉表单 / 查询筛选区 / 指标卡全套,内置 valueType 渲染器和请求生命周期。一张表格的业务代码,从 200 行压到 30 行。
快速上手
npm i el-pro-components element-plus vue
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'el-pro-components/style.css' // 组件库自己的样式,记得导入
import App from './App.vue'
createApp(App).use(ElementPlus).mount('#app')
ProTable:一份 columns,表格 + 搜索栏 + 工具栏全有了
先看最典型的场景——用户列表:
<script setup>
const columns = [
{ prop: 'id', label: 'ID', valueType: 'indexBorder', width: 64, search: false },
{ prop: 'name', label: '姓名', width: 130 },
{ prop: 'role', label: '角色', valueType: 'tag',
valueEnum: { admin: { text: '管理员', color: 'danger' }, editor: { text: '编辑', color: 'primary' } } },
{ prop: 'amount', label: '金额', valueType: 'money', sortable: 'custom', search: false },
{ prop: 'actions', label: '操作', valueType: 'option' },
]
const request = async (params) => {
// params: { current, pageSize, ...搜索字段 }
const { data, total } = await fetchUsers(params)
return { data, total }
}
</script>
<template>
<ElProTable :columns="columns" :request="request" row-key="id" selection title="用户列表">
<template #actions="{ row }">
<ElButton link type="primary" @click="edit(row)">编辑</ElButton>
</template>
</ElProTable>
</template>
这一份代码你免费获得的东西:
- 搜索栏:列上不标
search: false就自动进搜索区,valueEnum自动变成下拉框 - 工具栏:刷新 / 密度切换 / 列设置(可拖拽排序、固定列)/ 全屏,开箱即用
- 请求生命周期:分页参数自动拼装、loading、翻页回顶、
persistence-key持久化用户的列配置和页大小 - valueType 渲染:
money千分位、tag按 valueEnum 上色、dateTime/status/indexBorder……不用再手写 formatter - 轮询:
:polling="2000",监控类页面两行配置搞定
进阶能力也都在:多级表头(children 嵌套)、树形数据、展开行、合并单元格(merge-fields)、受控数据源(data-source 替代 request)、行内编辑(见下文)。
ProForm:联动、分组、动态数组,schema 一把梭
<script setup>
const model = reactive({ name: '', type: 'a', extra: '', contacts: [{ cname: '', phone: '' }] })
const columns = [
{
valueType: 'group', label: '基本信息', groupProps: { collapsible: true },
columns: [{ prop: 'name', label: '姓名', valueType: 'input',
rules: [{ required: true, message: '请输入姓名' }] }],
},
{ prop: 'type', label: '类型', valueType: 'radio',
valueEnum: { a: { text: '类型A' }, b: { text: '类型B' } } },
// 列级联动:只有类型A才显示
{ prop: 'extra', label: '附加说明', valueType: 'input',
dependency: { dependsOn: ['type'], visible: (v) => v.type === 'a' } },
// formList:动态增删的子表单
{ prop: 'contacts', label: '联系人', valueType: 'formList', formSpan: 24,
children: [
{ prop: 'cname', label: '姓名', valueType: 'input' },
{ prop: 'phone', label: '电话', valueType: 'input' },
] },
]
const onSubmit = async (values) => { await save(values); return true }
</script>
<template>
<ElProForm :columns="columns" :model="model" :span="8" @submit="onSubmit" />
</template>
提交/重置按钮是默认带的,校验、重置、valuesChange 事件都是内置的。跨字段的「任意子树级联」用 ElProFormDependency(作用域插槽拿依赖字段值),短信验证码输入框用 ElProFormCaptcha(自带 60s 倒计时,发送失败不进倒计时)。
弹窗 / 抽屉表单:trigger 插槽直接包住按钮
<ElProModalForm v-model:open="open" :columns="modalColumns" title="新建" :on-finish="onFinish">
<template #trigger><ElButton type="primary">新建</ElButton></template>
</ElProModalForm>
on-finish 返回 true 自动关弹窗,返回 false 或抛错留在弹窗里继续改——「接口炸了把用户刚填的东西丢掉」这种事故不会发生。ElProDrawerForm 同款 API。
行内编辑:编辑/保存/删除按钮自动渲染
<ElProEditableTable
:columns="editColumns" :data-source="rows" row-key="id"
:editable="{ type: 'multiple', onSave: async (key, row) => { await save(row); return true } }"
/>
type: 'single':一次只编辑一行,点另一行会先保存当前行(保存失败不切换)- 保存前按列上的
rules校验草稿;onSave返回false行留在编辑态 - 新增行靠
onSave的回包拿后端主键,返回对象会合并进该行
全家福清单(v0.1.0)
| 分类 | 组件 |
|---|---|
| 表格 | ElProTable、ElProEditableTable |
| 表单 | ElProForm、ElProStepsForm、ElProModalForm、ElProDrawerForm、ProFormGroup、ElProFormDependency、ElProFormCaptcha、ElProFieldSet |
| 筛选 | ElProQueryFilter、ElProLightFilter |
| 展示 | ElProDescriptions、ElProList、ElProCard、ElProCheckCard(Group)、ElProStatistic(Card/Group)、ElProSkeleton、ElProCardDivider |
| 布局 | ElProLayout、ElProPageContainer、ElProPageHeader、ElProFooterToolbar |
工具函数也直接导出:enumToOptions / formatDate / formatFromNow / formatQuarter / getISOWeek / parseDate / formatNumber / useTable,写需求时顺手就能用。
定位与边界
说实话的版本:
- ✅ 适合:Vue3 + Element Plus 技术栈的中后台/管理端,想省 CRUD 模板工作量
- ✅ API 心智对齐 antd ProComponents——
columns+valueEnum+request这套核心概念和 React 版同名同义。你在 React 项目里学过的肌肉记忆直接复用,迁移成本接近零;这也是我封它的第一原则:让「从 React 转 Vue」的同学不需要重新学一遍 - ⚠️ 0.1.0 早期版本,API 可能还会调;文档站还在完善中,先看 GitHub README 和类型提示
- 🚫 不打算替代 Element Plus——它是站在 EP 肩膀上的高阶封装,
el-*组件想混用随时混
最后
从 React 的 ProComponents 用到 Vue 自己封一套,中间最深的感受是:好工具的价值不只是省时间,而是让你不再容忍重复劳动。这个库还在早期,但核心链路(表格 → 表单 → 弹窗)已经在我自己的项目里跑起来了。
仓库里 README 有完整的安装说明和示例,后续会补文档站和更多 valueType。如果你也是从 React 转 Vue 的,或者这库帮你省了时间,去给个 Star 就是最大的鼓励;踩到坑欢迎提 issue,看到就修。
📖 在线文档(含示例):april-zheng.github.io/el-pro-comp… 🐙 github.com/April-Zheng… 📦 www.npmjs.com/package/el-…