# SuperElementJs
**Repository Path**: hashan/super-element-js
## Basic Information
- **Project Name**: SuperElementJs
- **Description**: 🎯 Schema 驱动:通过后端返回的 `schemaConfig` 一次性描述页面的:搜索、表单、弹窗等所有结构
🎨 若依风格兼容:内置对若依菜单 / 路由 / 字典 / 分页风格的支持
🔌 可插拔模板页:`SchemaView` 只是一个内置模板,你可以很容易开发"长得不一样"的模板页
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-01-22
- **Last Updated**: 2026-01-26
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 🚀 superElement
**superElement 解决后台管理系统中,80%的CRUD工作**







[快速开始](./README.md) | [schema配置](./doc/schema-config.md) | [开发指南](./doc/devDoce.md) | [演示项目](https://gitee.com/hashan/admin-x)
---
## 🌈 介绍
> **📦 关于本包**
> 本 npm 包提供了 `SchemaView` 模板页,适用于大多数简单的 CRUD 页面场景。如果你需要进行二次开发、自定义模板页或扩展功能,请访问 [Gitee 仓库](https://gitee.com/hashan/super-element-js.git) 获取完整源码。
>
> **💻 演示项目**
> 由于未搭建在线演示服务器,您可以访问 [演示项目仓库](https://gitee.com/hashan/admin-x) 下载到本地运行查看效果。
>
>**📘schema配置文档** [schema文档](./doc/schema-config.md)
>
>**🧭开发指南**
> 如果您需要进行二次开发,仔细阅读开发指南对您有帮助[开发指南](./doc/devDoce.md)
在中后台管理系统开发中,大量页面在 UI 布局、业务逻辑上高度相似。传统的开发方式往往需要复制粘贴页面代码,稍作修改后实现 CRUD 功能,导致大量重复性工作。
前端工程师的时间被这些重复的 CRUD 页面所消耗,既无法提升自身技术能力,也影响了项目整体开发效率。
**SuperElement** 基于 JSON Schema 描述页面的方式,将重复性页面沉淀为**可复用的模板页**,解放生产力。让前端工程师能够专注于更有价值的业务开发,或持续沉淀项目中的通用页面为模板,从而显著提升开发效率和代码质量。
---
## ✨ 特性
- 🎯 **Schema 驱动**:通过后端返回的 `schemaConfig` 一次性描述表格、搜索、表单、弹窗等所有结构
- 🎨 **若依风格兼容**:内置对若依 字典 / 分页风格的支持
- 🔌 **可插拔模板页**:`SchemaView` 只是一个内置模板,你可以很容易开发"长得不一样"的模板页
- ⚡ **函数式 API 参数配置**:通过 `apiParamsConfig`函数,统一管理请求参数
---
## 📦 安装
```bash
npm install super-element-js
# 或
yarn add super-element-js
# 或
pnpm add super-element-js
```
---
## 📺演示
>使用superElementJs,渲染的页面 👇






---
## 🚀 快速开始
> **💡 提示**
> 这里的“快速开始”只关注前端如何使用 `superElement`,包括:初始化引擎、路由配置与使用,以及**完全前端配置模式**。
> 更完整的后端 JSON Schema 配置与高级能力,请看后面的 **进阶配置** 章节。
### 1️⃣ 初始化引擎
在一个典型的后台项目中,推荐由后端返回整棵模型 / 菜单配置,然后在前端一次性初始化引擎(`createSchemaViewEngine`):
```javascript
// 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` 使用,下面是简化示例:
```vue
```
这种模式不依赖后端 JSON Schema,非常适合:
- 在现有项目中快速引入一个基于 schema 的 CRUD 页
- Demo / PoC 验证
- 逐步把“写死的页面”迁移为 Schema 驱动的配置
---
## ⚙️ 进阶配置
> 本章节对应完整的后端 JSON Schema 配置、API 配置、前端 `apiParamsConfig` 以及**配置校验**能力,更适合中大型项目或团队规范化接入。
### 1️⃣ 后端配置 JSON Schema 并提供接口
在后端服务(Node.js、Java 等)中,需要配置 JSON Schema 并提供一个接口返回解析后的配置。以 Node.js 为例(参考 `super-node` 实现):
**目录结构:**
```bash
your-backend/
├── model/
│ ├── index.js # 解析 model 配置的入口
│ └── model.js # JSON Schema 配置文件
├── app/
│ ├── controller/
│ │ └── project/
│ │ └── ProjectController.js
│ ├── service/
│ │ └── project/
│ │ └── project.js
│ └── router/
│ └── project/
│ └── project.js
```
**1.1 创建 Controller:**
```javascript
// 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:**
```javascript
// 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 配置路由:**
```javascript
// 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` 建议返回如下结构:
```json
{
"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 定义页面结构(字段 + 表格 + 搜索 + 表单等):
```javascript
// 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` 来关联后端的模型:
```javascript
// 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`:
```javascript
// 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`:
```js
// /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,
},
}),
},
// ... 更多模块配置
};
```
在初始化引擎时传入:
```js
createSchemaViewEngine({
models,
request,
apiParamsConfig,
});
```
引擎内部会在 `modelStore.setModels()` 时自动把 `apiParamsConfig[key]` 合并进对应菜单项的 `schemaConfig.api.params`,从而在请求列表 / 详情 / 新增 / 修改 / 删除时,自动套用你定义的参数拼装逻辑。
---
### 5️⃣ 开启配置校验(开发环境)
**如何在你的项目中开启校验(推荐只在开发环境开启):**
1. 在主项目入口(例如 `main.js`)中,在开发环境设置全局开关:
```js
// main.js(示意)
if (import.meta.env.DEV) {
// 显式打开 superElement 配置校验
window.__SUPER_ELEMENT_DEV__ = true;
}
```
2. 当 `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`)
3. 如果存在错误:
- 在控制台输出详细错误信息
- 抛出异常中断当前页面渲染,避免“带病上线”
4. 如果仅存在警告:
- 以 `console.warn` 的形式输出提示,但不会中断渲染
生产环境下,`isDev` 为 `false` 时会直接跳过校验,不产生任何性能损耗,非常适合作为团队内部的“配置规范守护神”。
## 📄 许可证
[MIT](./LICENSE) © 2026 superElement
---
**如果这个项目对你有帮助,请给它一个 ⭐ Star!**
Made with ❤️ by [Hashan](https://gitee.com/hashan)