super-element-js
v1.0.1
Published
Schema-driven CRUD page rendering engine
Maintainers
Readme
🚀 superElement
superElement 解决后台管理系统中,80%的CRUD工作


🌈 介绍
📦 关于本包
本 npm 包提供了SchemaView模板页,适用于大多数简单的 CRUD 页面场景。如果你需要进行二次开发、自定义模板页或扩展功能,请访问 Gitee 仓库 获取完整源码。💻 演示项目
由于未搭建在线演示服务器,您可以访问 演示项目仓库 下载到本地运行查看效果。📘schema配置文档 schema文档
🧭开发指南 如果您需要进行二次开发,仔细阅读开发指南对您有帮助开发指南
在中后台管理系统开发中,大量页面在 UI 布局、业务逻辑上高度相似。传统的开发方式往往需要复制粘贴页面代码,稍作修改后实现 CRUD 功能,导致大量重复性工作。
前端工程师的时间被这些重复的 CRUD 页面所消耗,既无法提升自身技术能力,也影响了项目整体开发效率。
SuperElement 基于 JSON Schema 描述页面的方式,将重复性页面沉淀为可复用的模板页,解放生产力。让前端工程师能够专注于更有价值的业务开发,或持续沉淀项目中的通用页面为模板,从而显著提升开发效率和代码质量。
✨ 特性
- 🎯 Schema 驱动:通过后端返回的
schemaConfig一次性描述表格、搜索、表单、弹窗等所有结构 - 🎨 若依风格兼容:内置对若依 字典 / 分页风格的支持
- 🔌 可插拔模板页:
SchemaView只是一个内置模板,你可以很容易开发"长得不一样"的模板页 - ⚡ 函数式 API 参数配置:通过
apiParamsConfig函数,统一管理请求参数
📦 安装
npm install super-element-js
# 或
yarn add super-element-js
# 或
pnpm add super-element-js📺演示
使用superElementJs,渲染的页面 👇
![]()
![]()
![]()
![]()
![]()
🚀 快速开始
💡 提示
这里的“快速开始”只关注前端如何使用superElement,包括:初始化引擎、路由配置与使用,以及完全前端配置模式。
更完整的后端 JSON Schema 配置与高级能力,请看后面的 进阶配置 章节。
1️⃣ 初始化引擎
在一个典型的后台项目中,推荐由后端返回整棵模型 / 菜单配置,然后在前端一次性初始化引擎(createSchemaViewEngine):
// main.js
import { createApp } from "vue";
import { createPinia } from "pinia";
import { createSchemaViewEngine } from "super-element-js";
import App from "./App.vue";
import request from "@/common/request"; // 你项目中封装的请求函数(推荐)
import { apiParamsConfig } from "@/config/api-params-config"; // API 参数配置(前端补充)
import { getModelInfo } from "@/superElementConfig/super-api"; // 获取 schema 配置的 API
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
async function initApp() {
const res = await getModelInfo();
if (!res || !res.success || !res.data) return;
const { menu } = res.data;
const models = menu; // 即后端返回的菜单 / 模型配置数组
createSchemaViewEngine({
models, // schema 配置数组
request, // 请求函数(推荐传入你项目封装的 request)
dictApi: "/system/dict/data/list", // 可选:字典获取 API 接口地址,默认 '/system/dict/data/list'
apiParamsConfig, // 前端补充的 API 参数配置
pinia, // 传入主项目的 Pinia 实例,确保使用同一个 store
});
app.mount("#app");
}
initApp();参数说明:
options.models(Array):后端返回的模型配置数组(通常是菜单树)options.request(Function):请求函数,不传则使用内部默认实现options.dictApi(String):字典获取 API 接口地址,默认'/system/dict/data/list'options.apiParamsConfig(Object):前端补充的 API 参数配置options.pinia(Pinia):Pinia 实例,确保使用同一个 store
2️⃣ JsonSchema前端配置模式
如果你暂时没有后端 JSON Schema,也可以完全在前端写一个 schemaConfig 对象,直接传给 SchemaView 使用,下面是简化示例:
<template>
<SchemaView :schemaConfig="productSchemaConfig" />
</template>
<script setup>
import { SchemaView } from "super-element-js";
const productSchemaConfig = {
key: "product",
name: "商品管理",
menuType: "module",
moduleType: "schema",
route: "system/product",
schemaConfig: {
// 1) API 配置:列表 / 详情 / 新增 / 修改 / 删除
api: {
list: "/api/proj/product/list",
detail: "/api/proj/product/:product_id",
create: "/api/proj/product",
update: "/api/proj/product",
delete: "/api/proj/product/:product_id",
params: {
list: (ctx) => ({
query: ctx.apiParams || {},
}),
detail: (ctx) => ({
path: { product_id: ctx.row.product_id },
}),
create: (ctx) => ({
body: ctx.form || {},
}),
update: (ctx) => ({
body: ctx.form || {},
}),
delete: (ctx) => ({
path: { product_id: ctx.row.product_id },
}),
},
},
// 2) JSON Schema:字段、表格、搜索、表单等配置(节选)
schema: {
type: "object",
properties: {
product_id: {
type: "string",
label: "商品ID",
tableOption: {
width: 300,
"show-overflow-tooltip": true,
},
editFormOption: {
comType: "input",
disabled: true,
},
detailPanelOption: {},
},
product_name: {
type: "string",
label: "商品名称",
maxLength: 20,
minLength: 3,
tableOption: { width: 200 },
searchOption: {
comType: "dynamicSelect",
api: "/api/proj/product_enum/list",
},
createFormOption: {
comType: "input",
default: "哲玄新课程",
rules: [
{ required: true, message: "商品名称不能为空" },
{ min: 3, max: 20, message: "商品名称长度在 3 到 20 个字符" },
],
},
editFormOption: {
comType: "input",
rules: [
{ required: true, message: "商品名称不能为空" },
{ min: 3, max: 20, message: "商品名称长度在 3 到 20 个字符" },
],
},
detailPanelOption: {},
},
// ... 价格、库存、创建时间等字段(同 super-admin 示例)
},
required: ["product_name"],
},
// 3) 表格与按钮配置
tableConfig: {
comType: "tablePanel",
headerButtons: [
{
label: "添加商品",
eventKey: "showComponent",
eventOption: { comName: "createForm" },
type: "primary",
plain: true,
},
],
rowButtons: [
{
label: "详情",
eventKey: "showComponent",
eventOption: { comName: "detailPanel" },
type: "primary",
},
{
label: "修改",
eventKey: "showComponent",
eventOption: { comName: "editForm" },
type: "warning",
},
{
label: "删除",
eventKey: "remove",
eventOption: {
params: { product_id: "schema::product_id" },
},
type: "danger",
},
],
},
// 4) 组件级别配置:新增 / 编辑 / 详情弹窗
componentConfig: {
createForm: {
title: "添加商品",
saveBtnText: "保存",
},
editForm: {
mainKey: "product_id",
title: "编辑商品",
saveBtnText: "保存",
},
detailPanel: {
mainKey: "product_id",
title: "商品详情",
},
},
},
};
</script>这种模式不依赖后端 JSON Schema,非常适合:
- 在现有项目中快速引入一个基于 schema 的 CRUD 页
- Demo / PoC 验证
- 逐步把“写死的页面”迁移为 Schema 驱动的配置
⚙️ 进阶配置
本章节对应完整的后端 JSON Schema 配置、API 配置、前端
apiParamsConfig以及配置校验能力,更适合中大型项目或团队规范化接入。
1️⃣ 后端配置 JSON Schema 并提供接口
在后端服务(Node.js、Java 等)中,需要配置 JSON Schema 并提供一个接口返回解析后的配置。以 Node.js 为例(参考 super-node 实现):
目录结构:
your-backend/
├── model/
│ ├── index.js # 解析 model 配置的入口
│ └── model.js # JSON Schema 配置文件
├── app/
│ ├── controller/
│ │ └── project/
│ │ └── ProjectController.js
│ ├── service/
│ │ └── project/
│ │ └── project.js
│ └── router/
│ └── project/
│ └── project.js1.1 创建 Controller:
// app/controller/project/ProjectController.js
module.exports = (app) => {
const BaseController = require("../base")(app);
return class ProjectController extends BaseController {
getProject(ctx) {
const projectService = app.service?.project?.project;
if (!projectService) throw new Error("Service 未加载");
const projConfig = projectService.get();
if (!projConfig) {
return this.fail(ctx, "获取项目异常", 50000);
}
this.success(ctx, projConfig);
}
};
};1.2 创建 Service:
// app/service/project/project.js
module.exports = (app) => {
const BaseService = require("../base")(app);
// 从 model/index.js 加载配置
const modelList = require("../../../model/index")(app);
return new (class ProjectService extends BaseService {
get() {
const projConfig = modelList[0].model;
return projConfig;
}
})();
};1.3 配置路由:
// app/router/project/project.js
module.exports = (app, router) => {
const controller = app.controller?.project?.ProjectController;
if (!controller) throw new Error("Controller 未加载");
router.get("/api/project", controller.getProject.bind(controller));
};1.4 接口返回格式:
接口 /api/project 建议返回如下结构:
{
"success": true,
"data": {
"model": "dashboard",
"name": "电商系统",
"menu": [
{
"key": "product",
"name": "商品管理",
"menuType": "module",
"moduleType": "schema",
"route": "system/product",
"schemaConfig": { /* ... */ }
}
]
}
}2️⃣ 配置 JSON Schema 结构
在后端 model/model.js 中,通过 JSON Schema 定义页面结构(字段 + 表格 + 搜索 + 表单等):
// model/model.js
module.exports = {
model: "dashboard",
name: "电商系统",
menu: [
{
key: "product", // 唯一标识,对应路由中的 key
name: "商品管理",
menuType: "module",
moduleType: "schema",
route: "system/product", // 路由路径
schemaConfig: {
// API 配置
api: {
list: "/api/proj/product/list",
detail: "/api/proj/product/:product_id",
create: "/api/proj/product",
update: "/api/proj/product",
delete: "/api/proj/product/:product_id",
params: {}, // 函数无法 JSON 序列化,留空,由前端 apiParamsConfig 补充
},
// JSON Schema 定义
schema: {
type: "object",
properties: {
product_id: {
type: "string",
label: "商品ID",
tableOption: {
width: 300,
"show-overflow-tooltip": true,
},
editFormOption: {
comType: "input",
disabled: true,
},
},
product_name: {
type: "string",
label: "商品名称",
maxLength: 20,
minLength: 3,
tableOption: {
width: 200,
},
searchOption: {
comType: "input",
default: "",
},
createFormOption: {
comType: "input",
default: "",
rules: [
{ required: true, message: "商品名称不能为空" },
{ min: 3, max: 20, message: "商品名称长度在 3 到 20 个字符" },
],
},
editFormOption: {
comType: "input",
rules: [{ required: true, message: "商品名称不能为空" }],
},
},
// ... 更多字段
},
required: ["product_name"],
},
// 表格配置
tableConfig: {
comType: "table",
},
// 搜索配置
searchConfig: {},
},
},
// ... 更多菜单项
],
};关键配置说明:
key:菜单项的唯一标识,必须与路由中的key一一对应schemaConfig.api:定义 CRUD 接口地址schemaConfig.schema:JSON Schema 定义,字段中通过xxxOption扩展表格 / 搜索 / 表单行为:tableOption:表格列配置searchOption:搜索区域配置createFormOption:新增表单配置editFormOption:编辑表单配置
3️⃣ 在路由中配置并使用 SchemaView
当你采用“后端驱动模型 + 引擎初始化”的模式时,路由只需要指向内置模板页 SchemaView,并在路由query 中配置 key 来关联后端的模型:
// router/index.js
import { SchemaView } from "super-element-js";
const routes = [
{
path: "/system/product",
component: SchemaView,
meta: {
title: "商品管理",
key: "product", // 对应后端 model 配置中的 key
},
},
];关键点:
- 路由query
key必须与后端model配置中的key一致
若采用若依动态路由风格,可以在路由过滤阶段统一把 schemaView 映射为 SchemaView:
// store/permission.js(示意)
import { SchemaView } from "super-element-js";
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
return asyncRouterMap.filter((route) => {
if (type && route.children) {
route.children = filterChildren(route.children);
}
if (route.component) {
if (route.component === "Layout") {
route.component = Layout;
} else if (route.component === "schemaView") {
// 约定:后端 component = 'schemaView' 时,渲染 SchemaView 模板页
route.component = SchemaView;
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, type);
} else {
delete route["children"];
delete route["redirect"];
}
return true;
});
}4️⃣ API 配置与 apiParamsConfig(前端补充)
由于函数无法 JSON 序列化,后端通常只返回 api.xxx 的 URL,参数拼装逻辑放在前端统一维护。推荐在前端声明一个 apiParamsConfig:
// /src/config/api-params-config.js
export const apiParamsConfig = {
product: {
// 商品列表:合并搜索参数
list: (ctx) => ({
query: ctx.apiParams || {},
}),
// 商品详情:从行数据中取主键 product_id,支持 camelCase / snake_case
detail: (ctx) => ({
path: {
product_id: ctx.row.product_id ?? ctx.row.productId,
},
}),
// 新增商品:直接提交表单数据
create: (ctx) => ({
body: ctx.form || {},
}),
// 修改商品:直接提交表单数据
update: (ctx) => ({
body: ctx.form || {},
}),
// 删除商品:从当前行取 product_id 作为 path 参数
delete: (ctx) => ({
path: {
product_id: ctx.row.product_id ?? ctx.row.productId,
},
}),
},
// ... 更多模块配置
};在初始化引擎时传入:
createSchemaViewEngine({
models,
request,
apiParamsConfig,
});引擎内部会在 modelStore.setModels() 时自动把 apiParamsConfig[key] 合并进对应菜单项的 schemaConfig.api.params,从而在请求列表 / 详情 / 新增 / 修改 / 删除时,自动套用你定义的参数拼装逻辑。
5️⃣ 开启配置校验(开发环境)
如何在你的项目中开启校验(推荐只在开发环境开启):
- 在主项目入口(例如
main.js)中,在开发环境设置全局开关:
// main.js(示意)
if (import.meta.env.DEV) {
// 显式打开 superElement 配置校验
window.__SUPER_ELEMENT_DEV__ = true;
}- 当
window.__SUPER_ELEMENT_DEV__ === true,或检测到 Vue DevTools /import.meta.env.DEV === 'development'时,validateSchemaConfig会在构建schemaConfig时自动运行:
- 校验必填字段:如
key、name、schemaConfig、moduleType等 - 校验 API 配置:是否缺失
list,detail路径格式是否合理等 - 校验 Schema 配置:字段类型、
comType是否已注册、rules是否为数组等 - 校验 TableConfig:
comType是否在允许范围内(如tablePanel | treeTablePanel)
- 如果存在错误:
- 在控制台输出详细错误信息
- 抛出异常中断当前页面渲染,避免“带病上线”
- 如果仅存在警告:
- 以
console.warn的形式输出提示,但不会中断渲染
生产环境下,isDev 为 false 时会直接跳过校验,不产生任何性能损耗,非常适合作为团队内部的“配置规范守护神”。
📄 许可证
MIT © 2026 superElement
如果这个项目对你有帮助,请给它一个 ⭐ Star!
Made with ❤️ by Hashan

