element-engin
v1.0.0
Published
基于 Element Plus 的页面搭建引擎:通过 TS/JS 配置驱动生成后台 CRUD 管理页面
Maintainers
Readme
element-engin
基于 Element Plus 的页面搭建引擎:通过 TypeScript / JavaScript 页面配置(definePage)驱动,自动生成具备 增删改查(CRUD) 能力的后台管理页面。
- 声明式配置:表格、搜索、表单、分页、接口
- RESTful 默认 + 单操作自定义覆盖
- 生命周期钩子:
before*/after*/onError - 默认提交 Loading、成功/失败 Notification
- 完整 TypeScript 类型
安装
npm install element-engin
npm install vue element-plus # peerDependencies在入口引入 Element Plus 样式:
import 'element-plus/dist/index.css'
import 'element-engin/style.css'快速开始
1. 定义页面配置
// pages/user.ts
import { definePage } from 'element-engin'
export const userPage = definePage({
page: { title: '用户管理' },
columns: [
{ prop: 'name', label: '姓名', width: 120 },
{ prop: 'email', label: '邮箱' },
],
search: [
{ prop: 'name', label: '姓名', component: 'Input' },
],
form: {
create: {
fields: [
{ prop: 'name', label: '姓名', component: 'Input', required: true },
{ prop: 'email', label: '邮箱', component: 'Input', required: true },
],
},
},
apis: {
resource: '/api/users', // RESTful 自动生成 list/create/update/delete/detail
},
})2. 挂载 PageEngine
<script setup lang="ts">
import { PageEngine } from 'element-engin'
import { userPage } from './pages/user'
</script>
<template>
<PageEngine :config="userPage" />
</template>3. 本地演示
仓库内置完整 Demo(Mock API + 钩子 + 自定义接口):
npm run demo详见 examples/demo。
RESTful 接口规范
配置 apis.resource 后,未单独声明的操作按 RESTful 默认推导:
| 操作 | Method | URL | 入参通道 |
|------|--------|-----|----------|
| list | GET | {resource} | query |
| create | POST | {resource} | body |
| update | PUT | {resource}/:id | body |
| delete | DELETE | {resource}/:id | query |
| detail | GET | {resource}/:id | query |
- 主键默认字段名
id,通过apis.idField修改;URL 中:id自动替换为行数据对应字段值 - 任意操作可 单独覆盖,不影响其他操作:
apis: {
resource: '/api/users',
create: {
url: '/api/custom/create-user',
method: 'POST',
transformParams: ({ formData }) => ({ ...formData }),
},
}未配置且无 resource 可推导的接口,对应 UI 能力自动隐藏(如无 delete 则不显示删除按钮)。
transformParams
为单个 CRUD 接口配置入参转换函数,在请求发出前执行:
apis: {
resource: '/api/users',
list: {
transformParams: ({ search, pagination }) => ({
...search,
page: pagination?.page,
pageSize: pagination?.pageSize,
}),
},
update: {
transformParams: ({ formData, row }) => ({
id: row?.id,
...formData,
}),
},
}上下文 TransformParamsContext:
| 字段 | 适用操作 |
|------|----------|
| action | 全部 |
| search | list |
| pagination | list |
| formData | create / update |
| row | update / delete / detail |
未配置 transformParams 时引擎使用内置默认:list 合并 search + 分页;create/update 使用 formData。
responseMapping
从接口响应中提取数据,路径以 . 分隔:
apis: {
resource: '/api/users',
list: {
responseMapping: { list: 'data.list', total: 'data.total' },
},
detail: {
responseMapping: { detail: 'data' },
},
}未配置时的兜底:list → data.list / 响应数组;detail → 响应体本身。
生命周期钩子
在 hooks 中定义,按操作类型在请求各阶段触发:
| 钩子 | 时机 | 说明 |
|------|------|------|
| beforeList / beforeCreate / beforeUpdate / beforeDelete | 请求发出前 | 返回 false 可中断请求 |
| afterList / afterCreate / afterUpdate / afterDelete | 请求成功后 | 可访问 response |
| onError | 任意请求失败 | 与默认错误提示配合使用 |
hooks: {
afterList: ({ response, engine }) => {
console.log('列表加载完成', response)
},
beforeDelete: ({ row }) => {
return row?.status !== 'locked' // false 阻止删除
},
afterDelete: ({ row, engine }) => {
engine.showMessage({ type: 'success', message: `已删除 ${row?.name}` })
},
onError: ({ action, error }) => {
console.error(action, error)
},
}错误提示职责:
create/update失败:默认走form.*.notification.error(6.10),onError做日志/埋点等副作用list/delete/detail失败:默认 error Notification 由onError路径统一展示,可通过notification.list.error等配置
HookContext 常用字段: action、params、response、row、formData、error、engine
EngineInstance
钩子与 transformParams 中通过 ctx.engine 调用:
| 方法 | 说明 |
|------|------|
| refreshList() | 重新加载列表 |
| openDialog(mode, row?) | 打开新增/编辑弹窗(编辑走 detail 回显流程) |
| closeDialog() | 关闭弹窗 |
| getSearchParams() | 当前搜索条件快照 |
| getPagination() | 当前分页快照 |
| setSearchParams(params, opts?) | 合并搜索条件,默认回第 1 页并刷新 |
| resetSearch(opts?) | 重置搜索为默认值 |
| setPagination({ page, pageSize }, opts?) | 更新分页并刷新 |
| showNotification(options) | 右上角 Notification |
| showMessage(options) | 短提示 Message |
页面配置字段说明
顶层 PageConfig
| 字段 | 必填 | 说明 |
|------|------|------|
| columns | 是 | 表格列 |
| apis | 是 | CRUD 接口(至少配置 resource 或单项接口) |
| page | 否 | 标题、路由元信息 |
| search | 否 | 搜索区字段(与 FieldConfig 相同) |
| form | 否 | 新增/编辑表单 |
| pagination | 否 | 分页默认值(pageSize 默认 20) |
| notification | 否 | 页面级 Notification 默认 |
| hooks | 否 | 生命周期钩子 |
columns 列配置
| 字段 | 说明 |
|------|------|
| prop / label | 字段名 / 列标题 |
| width / minWidth | 列宽 |
| sortable / align / fixed | 排序、对齐、固定列 |
| formatter | (row, cellValue) => string 单元格格式化 |
search / form.fields 字段配置
| 字段 | 说明 |
|------|------|
| prop / label | 字段名 / 标签 |
| component | Input | Select | InputNumber | Switch | DatePicker(默认 Input) |
| required | 必填简写 |
| defaultValue | 默认值 |
| options | Select 选项 { label, value }[] |
| rules | 校验规则 |
| placeholder / disabled | 占位、禁用 |
form.create / form.update
| 字段 | 说明 |
|------|------|
| fields | 表单字段列表 |
| title | 弹窗标题 |
| labelWidth | 标签宽度 |
| submitLoading | 提交 Loading,默认 true |
| notification | 成功/失败 Notification(可 enabled: false 关闭) |
| useDetail | 编辑时是否调 detail 接口回显,默认 false |
notification 优先级
表单提交成功/失败:form.create|update.notification > notification.create|update > notification 全局 > 内置默认文案。
列表/删除/详情失败:notification.list|delete|detail.error > notification.error > 内置默认。
注入 HTTP 客户端
默认使用内置 axios 实例。宿主项目可注入自己的实例(复用拦截器、baseURL):
import axios from 'axios'
import { setHttpClient } from 'element-engin'
const client = axios.create({ baseURL: '/api' })
setHttpClient(client)在挂载 PageEngine 之前调用。
导出 API
import {
definePage,
PageEngine,
resolveApis,
resolvePageVisibility,
validatePageConfig,
setHttpClient,
getHttpClient,
} from 'element-engin'
import type { PageConfig, HookContext, EngineInstance } from 'element-engin'开发
npm install
npm run typecheck # 类型检查
npm run test # 单元测试(157+)
npm run build # 构建 dist(ESM + CJS + d.ts)
npm run verify:build # 验证 exports / types / ESM / CJS 产物
npm run build:verify # build + verify 一键执行
npm run demo # 启动示例License
MIT
