devject-design 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +482 -162
- package/dist/core/builtin/advanced.d.ts +1 -0
- package/dist/core/builtin/basics.d.ts +1 -0
- package/dist/core/builtin/containers.d.ts +1 -0
- package/dist/core/builtin/editors.d.ts +1 -0
- package/dist/core/builtin/index.d.ts +1 -0
- package/dist/core/builtin/utils.d.ts +9 -0
- package/dist/core/editors.d.ts +17 -0
- package/dist/core/registry.d.ts +38 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.es.js +11843 -2762
- package/dist/index.umd.js +39 -1
- package/dist/pages/FormDesigner.d.ts +11 -1
- package/dist/style.css +1 -1
- package/dist/ui/PaletteItem.d.ts +2 -0
- package/dist/ui/PreviewDialog.d.ts +42 -1
- package/dist/ui/components/Checkbox.d.ts +11 -0
- package/dist/ui/components/Collapse.d.ts +11 -0
- package/dist/ui/components/FileUpload.d.ts +11 -0
- package/dist/ui/components/FlexRow.d.ts +11 -0
- package/dist/ui/components/ImageUpload.d.ts +11 -0
- package/dist/ui/components/Input.d.ts +11 -0
- package/dist/ui/components/Radio.d.ts +11 -0
- package/dist/ui/components/Select.d.ts +11 -0
- package/dist/ui/components/StaticTable.d.ts +7 -0
- package/dist/ui/components/Switch.d.ts +11 -0
- package/dist/ui/components/Table.d.ts +11 -0
- package/dist/ui/components/Tabs.d.ts +11 -0
- package/dist/ui/components/Textarea.d.ts +11 -0
- package/dist/ui/components/Title.d.ts +7 -0
- package/dist/ui/components/Tree.d.ts +7 -0
- package/dist/ui/editors/CollapseEditor.d.ts +5 -0
- package/dist/ui/editors/ExcelIOEditor.d.ts +5 -0
- package/dist/ui/editors/FlexLayoutEditor.d.ts +5 -0
- package/dist/ui/editors/JsonDataEditor.d.ts +9 -0
- package/dist/ui/editors/OptionsEditor.d.ts +9 -0
- package/dist/ui/editors/TableColumnsEditor.d.ts +10 -0
- package/dist/ui/editors/TabsEditor.d.ts +5 -0
- package/dist/ui/hooks/useValidator.d.ts +4 -0
- package/dist/ui/preview/FormRenderer.d.ts +15 -2
- package/dist/ui/state/designerState.d.ts +30 -1405
- package/dist/ui/state/dragState.d.ts +11 -6
- package/dist/ui/state/injectionKeys.d.ts +4 -0
- package/dist/ui/state/schemaOps.d.ts +1 -3
- package/dist/ui/state/types.d.ts +29 -92
- package/dist/ui/state/useDragLogic.d.ts +10 -0
- package/dist/ui/state/useHotkeys.d.ts +4 -0
- package/dist/ui/state/validator.d.ts +36 -0
- package/package.json +7 -2
- package/dist/ui/state/history.d.ts +0 -8413
package/README.md
CHANGED
|
@@ -1,162 +1,482 @@
|
|
|
1
|
-
# Devject Design
|
|
2
|
-
|
|
3
|
-
Devject Design 是一个基于 Vue 3 和 Element Plus 的可视化表单设计器与渲染器组件库。它允许用户通过拖拽方式快速创建表单布局,并支持将设计好的表单导出为 JSON 数据,或直接在应用中渲染。
|
|
4
|
-
|
|
5
|
-
## 特性
|
|
6
|
-
|
|
7
|
-
- ⚡ **基于 Vue 3 + TypeScript
|
|
8
|
-
- 🎨 **Element Plus 风格**:与 Element Plus UI 完美融合。
|
|
9
|
-
- 🧩 **可视化设计器**:支持拖拽、属性配置、实时预览。
|
|
10
|
-
- 📝 **表单渲染器**:根据 JSON
|
|
11
|
-
- 📤 **导入/导出**:支持 JSON 格式的布局与数据导入导出。
|
|
12
|
-
- 📊
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
import
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
1
|
+
# Devject Design
|
|
2
|
+
|
|
3
|
+
Devject Design 是一个基于 Vue 3 和 Element Plus 的可视化表单设计器与渲染器组件库。它允许用户通过拖拽方式快速创建表单布局,并支持将设计好的表单导出为 JSON 数据,或直接在应用中渲染。
|
|
4
|
+
|
|
5
|
+
## ✨ 特性
|
|
6
|
+
|
|
7
|
+
- ⚡ **基于 Vue 3 + TypeScript**:使用最新的技术栈,提供完整的类型定义。
|
|
8
|
+
- 🎨 **Element Plus 风格**:与 Element Plus UI 完美融合。
|
|
9
|
+
- 🧩 **可视化设计器**:支持拖拽、属性配置、实时预览。
|
|
10
|
+
- 📝 **表单渲染器**:根据 JSON 结构自动渲染表单,支持数据双向绑定与校验。
|
|
11
|
+
- 📤 **导入/导出**:支持 JSON 格式的布局与数据导入导出。
|
|
12
|
+
- 📊 **高级组件**:
|
|
13
|
+
- **静态表格 (StaticTable)**:支持 Excel 导入(自动识别表头、清空旧数据)与导出。
|
|
14
|
+
- **表格表单 (Table)**:动态表格组件,支持分页、增删改查及数据绑定。
|
|
15
|
+
- **树形控件 (Tree)**:支持层级路径格式(如 `父节点/子节点`)的 Excel 导入导出,支持父子关联配置。
|
|
16
|
+
- 🏗️ **复杂布局**:内置栅格布局 (FlexRow)、折叠面板 (Collapse)、标签页 (Tabs) 等容器组件。
|
|
17
|
+
|
|
18
|
+
## 📦 安装
|
|
19
|
+
|
|
20
|
+
使用 npm 或 yarn 安装:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install devject-design
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 依赖项
|
|
27
|
+
|
|
28
|
+
本库依赖 `vue` 和 `element-plus`,请确保项目中已安装:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install vue element-plus
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
如果使用表格/树形组件的 Excel 导入导出功能,还需要安装 `xlsx`:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install xlsx
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## ⚙️ 配置说明
|
|
41
|
+
|
|
42
|
+
本库支持通过 Props 配置上传和下载接口。
|
|
43
|
+
|
|
44
|
+
### 属性说明
|
|
45
|
+
|
|
46
|
+
`FormDesigner` 和 `FormRenderer` 组件都支持以下 Props:
|
|
47
|
+
|
|
48
|
+
| 属性名 | 说明 | 类型 | 默认值 |
|
|
49
|
+
| :--- |:---------------------------------------------| :--- | :--- |
|
|
50
|
+
| `upload-url` | 文件上传接口地址 | `string` | - |
|
|
51
|
+
| `download-url` | 文件下载/访问基础路径 | `string` | - |
|
|
52
|
+
| `upload-parse` | 上传响应解析路径 (例如 `data.url`,即为response.data.url) | `string` | `data` |
|
|
53
|
+
|
|
54
|
+
### 示例
|
|
55
|
+
|
|
56
|
+
在你的 Vite 项目中,你可以使用环境变量来传递这些值:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// .env
|
|
60
|
+
VITE_DEVJECT_UPLOAD_URL=/api/file/upload
|
|
61
|
+
VITE_DEVJECT_DOWNLOAD_URL=/api/file/download
|
|
62
|
+
VITE_DEVJECT_UPLOAD_PARSE=data.url
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```vue
|
|
66
|
+
<template>
|
|
67
|
+
<FormDesigner
|
|
68
|
+
:upload-url="uploadUrl"
|
|
69
|
+
:download-url="downloadUrl"
|
|
70
|
+
:upload-parse="uploadParse"
|
|
71
|
+
/>
|
|
72
|
+
</template>
|
|
73
|
+
|
|
74
|
+
<script setup lang="ts">
|
|
75
|
+
import { FormDesigner } from 'devject-design'
|
|
76
|
+
|
|
77
|
+
const uploadUrl = import.meta.env.VITE_DEVJECT_UPLOAD_URL
|
|
78
|
+
const downloadUrl = import.meta.env.VITE_DEVJECT_DOWNLOAD_URL
|
|
79
|
+
const uploadParse = import.meta.env.VITE_DEVJECT_UPLOAD_PARSE
|
|
80
|
+
</script>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 🚀 快速开始
|
|
84
|
+
|
|
85
|
+
### 全局注册
|
|
86
|
+
|
|
87
|
+
在你的入口文件(如 `main.ts`)中引入 Element Plus 和 Devject Design:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { createApp } from 'vue'
|
|
91
|
+
import App from './App.vue'
|
|
92
|
+
|
|
93
|
+
import ElementPlus from 'element-plus'
|
|
94
|
+
import 'element-plus/dist/index.css'
|
|
95
|
+
|
|
96
|
+
import DevjectDesign from 'devject-design'
|
|
97
|
+
import 'devject-design/dist/style.css'
|
|
98
|
+
|
|
99
|
+
const app = createApp(App)
|
|
100
|
+
|
|
101
|
+
app.use(ElementPlus)
|
|
102
|
+
app.use(DevjectDesign)
|
|
103
|
+
app.mount('#app')
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 使用表单设计器 (FormDesigner)
|
|
107
|
+
|
|
108
|
+
FormDesigner 支持通过 `v-model` 双向绑定布局数据,并提供了导入导出的方法。
|
|
109
|
+
|
|
110
|
+
```vue
|
|
111
|
+
<template>
|
|
112
|
+
<div style="width:100%;height: 100%;overflow: hidden">
|
|
113
|
+
<!-- 顶部操作栏示例 -->
|
|
114
|
+
<div>
|
|
115
|
+
<button @click="handleExport">导出布局</button>
|
|
116
|
+
<button @click="handleImport">导入布局</button>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<FormDesigner
|
|
120
|
+
ref="designerRef"
|
|
121
|
+
v-model="layoutSchema"
|
|
122
|
+
:upload-url="uploadUrl"
|
|
123
|
+
:download-url="downloadUrl"
|
|
124
|
+
:upload-parse="uploadParse"
|
|
125
|
+
/>
|
|
126
|
+
</div>
|
|
127
|
+
</template>
|
|
128
|
+
|
|
129
|
+
<script setup lang="ts">
|
|
130
|
+
import { ref } from 'vue'
|
|
131
|
+
import { FormDesigner } from 'devject-design'
|
|
132
|
+
import type { LayoutSchema } from 'devject-design'
|
|
133
|
+
|
|
134
|
+
const uploadUrl = import.meta.env.VITE_DEVJECT_UPLOAD_URL
|
|
135
|
+
const downloadUrl = import.meta.env.VITE_DEVJECT_DOWNLOAD_URL
|
|
136
|
+
const uploadParse = import.meta.env.VITE_DEVJECT_UPLOAD_PARSE
|
|
137
|
+
|
|
138
|
+
// 双向绑定布局数据
|
|
139
|
+
const layoutSchema = ref<LayoutSchema>()
|
|
140
|
+
const designerRef = ref()
|
|
141
|
+
|
|
142
|
+
// 调用组件方法导出
|
|
143
|
+
const handleExport = () => {
|
|
144
|
+
if (designerRef.value) {
|
|
145
|
+
const layout = designerRef.value.exportLayout()
|
|
146
|
+
console.log('Exported:', layout)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 调用组件方法导入
|
|
151
|
+
const handleImport = () => {
|
|
152
|
+
if (designerRef.value) {
|
|
153
|
+
designerRef.value.importLayout({
|
|
154
|
+
version: 1,
|
|
155
|
+
root: { children: [] }
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
</script>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 使用表单渲染器 (FormRenderer)
|
|
163
|
+
|
|
164
|
+
FormRenderer 支持通过 `v-model` 绑定表单数据,并提供了数据导入导出方法。
|
|
165
|
+
|
|
166
|
+
```vue
|
|
167
|
+
<template>
|
|
168
|
+
<div>
|
|
169
|
+
<!-- 操作按钮 -->
|
|
170
|
+
<button @click="getFormData">获取数据</button>
|
|
171
|
+
<button @click="setFormData">设置数据</button>
|
|
172
|
+
|
|
173
|
+
<FormRenderer
|
|
174
|
+
ref="rendererRef"
|
|
175
|
+
:schema="formSchema"
|
|
176
|
+
v-model="formData"
|
|
177
|
+
:upload-url="uploadUrl"
|
|
178
|
+
:download-url="downloadUrl"
|
|
179
|
+
:upload-parse="uploadParse"
|
|
180
|
+
/>
|
|
181
|
+
</div>
|
|
182
|
+
</template>
|
|
183
|
+
|
|
184
|
+
<script setup lang="ts">
|
|
185
|
+
import { ref } from 'vue'
|
|
186
|
+
import { FormRenderer } from 'devject-design'
|
|
187
|
+
import type { LayoutSchema, FormDataModel } from 'devject-design'
|
|
188
|
+
|
|
189
|
+
const uploadUrl = import.meta.env.VITE_DEVJECT_UPLOAD_URL
|
|
190
|
+
const downloadUrl = import.meta.env.VITE_DEVJECT_DOWNLOAD_URL
|
|
191
|
+
const uploadParse = import.meta.env.VITE_DEVJECT_UPLOAD_PARSE
|
|
192
|
+
|
|
193
|
+
const rendererRef = ref()
|
|
194
|
+
// 表单结构定义
|
|
195
|
+
const formSchema = ref<LayoutSchema>({ /* ... */ })
|
|
196
|
+
// 表单数据双向绑定
|
|
197
|
+
const formData = ref<FormDataModel>({})
|
|
198
|
+
|
|
199
|
+
// 调用组件方法获取数据
|
|
200
|
+
const getFormData = async () => {
|
|
201
|
+
if (rendererRef.value) {
|
|
202
|
+
try {
|
|
203
|
+
// 默认会先进行校验,校验通过后返回数据
|
|
204
|
+
const data = await rendererRef.value.exportData()
|
|
205
|
+
console.log('Form Data:', data)
|
|
206
|
+
} catch (e) {
|
|
207
|
+
console.error('Validation failed')
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// 调用组件方法设置数据
|
|
213
|
+
const setFormData = () => {
|
|
214
|
+
if (rendererRef.value) {
|
|
215
|
+
rendererRef.value.importData({ field1: 'value1' })
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
</script>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## 🧩 内置组件详解
|
|
222
|
+
|
|
223
|
+
除了基础的 Input, Select, Radio, Checkbox 外,本库还包含以下高级组件:
|
|
224
|
+
|
|
225
|
+
### 1. 静态表格 (StaticTable)
|
|
226
|
+
用于展示或编辑固定的行列数据。
|
|
227
|
+
- **Excel 导入**: 支持直接导入 `.xlsx` 文件。导入时会自动识别首行作为表头(列名),并**自动清空**旧的列配置和数据。
|
|
228
|
+
- **Excel 导出**: 支持将当前表格数据导出为 Excel 文件。
|
|
229
|
+
- **数据绑定**: 修改列标题不会丢失该列已有的数据。
|
|
230
|
+
|
|
231
|
+
### 2. 表格表单 (Table)
|
|
232
|
+
用于展示动态数据列表。
|
|
233
|
+
- **分页支持**: 可配置是否显示分页及每页条数。
|
|
234
|
+
- **增删改查**: 内置添加和删除行操作。
|
|
235
|
+
- **列配置**: 支持自定义列类型(文本、数字、下拉等)及校验规则。
|
|
236
|
+
|
|
237
|
+
### 3. 树形控件 (Tree)
|
|
238
|
+
用于展示层级数据。
|
|
239
|
+
- **Excel 导入**: 支持导入路径格式的 Excel(例如:`一级/二级/三级`),系统会自动解析为树形结构。
|
|
240
|
+
- **关联配置**: 提供`关联`开关。开启时,父子节点选中状态联动;关闭时,各节点独立选中。
|
|
241
|
+
- **缩进设置**: 可自定义树节点的缩进大小。
|
|
242
|
+
|
|
243
|
+
### 4. 布局组件
|
|
244
|
+
- **FlexRow**: 栅格布局,支持自定义列宽比例。
|
|
245
|
+
- **Collapse**: 折叠面板,支持多面板展开/收起。
|
|
246
|
+
- **Tabs**: 标签页布局,支持动态增删标签页。
|
|
247
|
+
|
|
248
|
+
## 📚 组件 API
|
|
249
|
+
|
|
250
|
+
### FormDesigner
|
|
251
|
+
|
|
252
|
+
表单设计器组件,提供完整的画布、组件库和属性面板。
|
|
253
|
+
|
|
254
|
+
#### Props
|
|
255
|
+
|
|
256
|
+
| 属性 | 说明 | 类型 | 默认值 |
|
|
257
|
+
| :--- | :--- | :--- | :--- |
|
|
258
|
+
| `modelValue` | 表单布局结构绑定 (v-model) | `LayoutSchema` | - |
|
|
259
|
+
| `upload-url` | 文件上传接口地址 | `string` | - |
|
|
260
|
+
| `download-url` | 文件下载/访问基础路径 | `string` | - |
|
|
261
|
+
| `upload-parse` | 上传响应解析路径 | `string` | `data` |
|
|
262
|
+
|
|
263
|
+
#### Exposed Methods
|
|
264
|
+
|
|
265
|
+
| 方法名 | 说明 | 参数 | 返回值 |
|
|
266
|
+
| :--- | :--- | :--- | :--- |
|
|
267
|
+
| `exportLayout` | 导出当前布局结构 | - | `LayoutSchema` |
|
|
268
|
+
| `importLayout` | 导入布局结构 | `json: LayoutSchema` | `void` |
|
|
269
|
+
|
|
270
|
+
### FormRenderer
|
|
271
|
+
|
|
272
|
+
表单渲染器组件,用于展示设计好的表单。
|
|
273
|
+
|
|
274
|
+
#### Props
|
|
275
|
+
|
|
276
|
+
| 属性 | 说明 | 类型 | 默认值 |
|
|
277
|
+
| :--- | :--- | :--- | :--- |
|
|
278
|
+
| `schema` | **(必填)** 表单布局结构对象 | `LayoutSchema` | - |
|
|
279
|
+
| `modelValue` | **(必填)** 表单数据绑定 (v-model) | `FormDataModel` | `{}` |
|
|
280
|
+
| `upload-url` | 文件上传接口地址 | `string` | - |
|
|
281
|
+
| `download-url` | 文件下载/访问基础路径 | `string` | - |
|
|
282
|
+
| `upload-parse` | 上传响应解析路径 | `string` | `data` |
|
|
283
|
+
|
|
284
|
+
#### Exposed Methods
|
|
285
|
+
|
|
286
|
+
| 方法名 | 说明 | 参数 | 返回值 |
|
|
287
|
+
| :--- | :--- | :--- | :--- |
|
|
288
|
+
| `exportData` | 导出当前表单数据 (默认进行校验) | `validateBeforeExport?: boolean` (默认 `true`) | `Promise<FormDataModel>` |
|
|
289
|
+
| `importData` | 导入表单数据 | `data: FormDataModel` | `void` |
|
|
290
|
+
| `validate` | 校验表单 | - | `Promise<boolean>` |
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
## 🛠 自定义组件开发
|
|
294
|
+
|
|
295
|
+
Devject Design 支持通过注册自定义组件来扩展设计器的能力。
|
|
296
|
+
|
|
297
|
+
### 1. 注册组件 API
|
|
298
|
+
|
|
299
|
+
使用 `registerComponent` 函数来注册一个新的组件。
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
import { registerComponent, type ComponentDefinition } from 'devject-design';
|
|
303
|
+
|
|
304
|
+
const myComponentDef: ComponentDefinition = {
|
|
305
|
+
type: 'my-custom-type', // 组件唯一标识
|
|
306
|
+
component: MyComponentVue, // Vue 组件对象
|
|
307
|
+
palette: {
|
|
308
|
+
label: '我的组件',
|
|
309
|
+
group: '自定义', // 在组件面板中的分组
|
|
310
|
+
icon: 'Operation' // (可选) 组件面板显示的图标名称 (支持所有 Element Plus 图标)
|
|
311
|
+
},
|
|
312
|
+
defaultProps: (id) => ({
|
|
313
|
+
id,
|
|
314
|
+
type: 'my-custom-type',
|
|
315
|
+
props: {
|
|
316
|
+
// 组件默认属性
|
|
317
|
+
someProp: 'defaultValue'
|
|
318
|
+
}
|
|
319
|
+
}),
|
|
320
|
+
// 自定义校验逻辑
|
|
321
|
+
validate: (value, node, formData) => {
|
|
322
|
+
if (!value) return '该项不能为空';
|
|
323
|
+
if (value.length < 5) return '长度至少为5';
|
|
324
|
+
return true; // 校验通过返回 true
|
|
325
|
+
},
|
|
326
|
+
// 可选:数据处理器
|
|
327
|
+
dataProcessor: {
|
|
328
|
+
import: (val) => val, // 导入时处理数据
|
|
329
|
+
export: (val) => val // 导出时处理数据
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
registerComponent(myComponentDef);
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### 2. 编写 Vue 组件
|
|
337
|
+
|
|
338
|
+
自定义组件会接收 `node` props,其中包含组件的配置信息。
|
|
339
|
+
|
|
340
|
+
```vue
|
|
341
|
+
<!-- MyComponent.vue -->
|
|
342
|
+
<template>
|
|
343
|
+
<div class="my-component">
|
|
344
|
+
<h3>{{ node.props.label || 'My Component' }}</h3>
|
|
345
|
+
<p>属性值: {{ node.props.someProp }}</p>
|
|
346
|
+
<!-- 如果是输入类组件,可以使用 inject 获取 formModel -->
|
|
347
|
+
</div>
|
|
348
|
+
</template>
|
|
349
|
+
|
|
350
|
+
<script setup lang="ts">
|
|
351
|
+
import type { SchemaNode } from 'devject-design';
|
|
352
|
+
|
|
353
|
+
defineProps<{
|
|
354
|
+
node: SchemaNode
|
|
355
|
+
}>();
|
|
356
|
+
</script>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### 3. 集成示例
|
|
360
|
+
|
|
361
|
+
在你的应用入口或组件初始化处进行注册:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import { registerComponent } from 'devject-design';
|
|
365
|
+
import MyCustomComponent from './MyCustomComponent.vue';
|
|
366
|
+
|
|
367
|
+
// 注册组件
|
|
368
|
+
registerComponent({
|
|
369
|
+
type: 'custom-widget',
|
|
370
|
+
component: MyCustomComponent,
|
|
371
|
+
palette: { label: '自定义控件', group: '业务组件' },
|
|
372
|
+
defaultProps: (id) => ({
|
|
373
|
+
id,
|
|
374
|
+
type: 'custom-widget',
|
|
375
|
+
props: { title: '默认标题' }
|
|
376
|
+
})
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### 4. 自定义属性编辑器
|
|
381
|
+
|
|
382
|
+
除了注册组件本身,你还可以为组件属性注册自定义编辑器。
|
|
383
|
+
|
|
384
|
+
#### 1. 编写编辑器组件
|
|
385
|
+
|
|
386
|
+
编辑器组件接收以下 Props:
|
|
387
|
+
- `modelValue`: 当前属性值
|
|
388
|
+
- `nodeId`: 当前选中的组件 ID
|
|
389
|
+
- 其他自定义 Props
|
|
390
|
+
|
|
391
|
+
```vue
|
|
392
|
+
<!-- MyColorEditor.vue -->
|
|
393
|
+
<template>
|
|
394
|
+
<el-color-picker :modelValue="modelValue" @change="$emit('update:modelValue', $event)" />
|
|
395
|
+
</template>
|
|
396
|
+
|
|
397
|
+
<script setup lang="ts">
|
|
398
|
+
defineProps<{
|
|
399
|
+
modelValue: string,
|
|
400
|
+
nodeId: string
|
|
401
|
+
}>();
|
|
402
|
+
defineEmits(['update:modelValue']);
|
|
403
|
+
</script>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
#### 2. 注册编辑器
|
|
407
|
+
|
|
408
|
+
使用 `registerEditor` 函数注册编辑器。
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
import { registerEditor } from 'devject-design';
|
|
412
|
+
import MyColorEditor from './MyColorEditor.vue';
|
|
413
|
+
|
|
414
|
+
registerEditor('my-color-editor', MyColorEditor);
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
#### 3. 在组件配置中使用
|
|
418
|
+
|
|
419
|
+
在 `propsConfig` 中引用已注册的编辑器名称。
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
registerComponent({
|
|
423
|
+
// ...
|
|
424
|
+
propsConfig: [
|
|
425
|
+
{
|
|
426
|
+
label: "颜色配置",
|
|
427
|
+
name: "textColor",
|
|
428
|
+
type: "custom",
|
|
429
|
+
editor: "my-color-editor" // 使用注册的编辑器名称
|
|
430
|
+
}
|
|
431
|
+
]
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## ✅ 表单校验
|
|
436
|
+
|
|
437
|
+
Devject Design 提供了一套灵活的表单校验机制,支持内置的必填校验和自定义的函数校验。
|
|
438
|
+
|
|
439
|
+
### 1. 必填校验
|
|
440
|
+
|
|
441
|
+
在设计器中选中组件,勾选"必填"属性即可开启。
|
|
442
|
+
- 系统会自动根据组件类型(如输入框、下拉框)生成相应的提示语,例如"请输入用户名"或"请选择城市"。
|
|
443
|
+
- 提示语生成逻辑:`请[输入/选择][组件标题]`。
|
|
444
|
+
|
|
445
|
+
### 2. 自定义校验
|
|
446
|
+
|
|
447
|
+
通过 `registerComponent` 注册组件时,可以提供 `validate` 函数来实现复杂的校验逻辑。
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
registerComponent({
|
|
451
|
+
// ... 其他配置
|
|
452
|
+
validate: (value, node, formData) => {
|
|
453
|
+
// value: 当前字段的值
|
|
454
|
+
// node: 当前组件的配置节点信息
|
|
455
|
+
// formData: 整个表单的数据对象
|
|
456
|
+
|
|
457
|
+
if (!value && node.props.required) {
|
|
458
|
+
return true; // 如果为空且必填,由内置必填规则处理,这里可以返回 true 跳过
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (value && value.length < 5) {
|
|
462
|
+
return '长度不能少于 5 个字符'; // 返回字符串作为错误提示
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// 支持异步校验 (返回 Promise)
|
|
466
|
+
// return fetch('/api/check?val=' + value).then(res => res.ok ? true : '校验失败');
|
|
467
|
+
|
|
468
|
+
return true; // 校验通过
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### 3. 触发校验
|
|
474
|
+
|
|
475
|
+
- **自动触发**:表单输入或失去焦点时自动触发。
|
|
476
|
+
- **手动触发**:通过 `FormRenderer` 的 `validate()` 方法。
|
|
477
|
+
- **导出时触发**:调用 `exportData()` 时默认会自动校验,校验失败则抛出异常。
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
## 📄 许可证
|
|
481
|
+
|
|
482
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerAdvanced(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerBasics(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerContainers(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerBuiltinEditors(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerBuiltins(): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PropConfigItem } from '../registry';
|
|
2
|
+
export declare function commonFieldConfig(includePlaceholder?: boolean): PropConfigItem[];
|
|
3
|
+
export declare const commonDefault: (label: string, fieldPrefix: string) => {
|
|
4
|
+
label: string;
|
|
5
|
+
field: string;
|
|
6
|
+
placeholder: string;
|
|
7
|
+
required: boolean;
|
|
8
|
+
labelWidth: number;
|
|
9
|
+
};
|