jianghu-ui 1.0.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 +376 -0
- package/dist/jianghu-ui.css +2318 -0
- package/dist/jianghu-ui.js +2 -0
- package/dist/jianghu-ui.js.LICENSE.txt +1 -0
- package/package.json +56 -0
- package/src/Design.stories.mdx +195 -0
- package/src/Introduction.stories.mdx +148 -0
- package/src/components/JhAddressSelect/JhAddressSelect.md +250 -0
- package/src/components/JhAddressSelect/JhAddressSelect.stories.js +282 -0
- package/src/components/JhAddressSelect/JhAddressSelect.vue +261 -0
- package/src/components/JhCard/JhCard.md +246 -0
- package/src/components/JhCard/JhCard.stories.js +688 -0
- package/src/components/JhCard/JhCard.vue +604 -0
- package/src/components/JhCheckCard/JhCheckCard.md +245 -0
- package/src/components/JhCheckCard/JhCheckCard.stories.js +750 -0
- package/src/components/JhCheckCard/JhCheckCard.vue +476 -0
- package/src/components/JhConfirmDialog/JhConfirmDialog.md +70 -0
- package/src/components/JhConfirmDialog/JhConfirmDialog.stories.js +550 -0
- package/src/components/JhConfirmDialog/JhConfirmDialog.vue +181 -0
- package/src/components/JhDateRangePicker/JhDateRangePicker.md +56 -0
- package/src/components/JhDateRangePicker/JhDateRangePicker.stories.js +320 -0
- package/src/components/JhDateRangePicker/JhDateRangePicker.vue +307 -0
- package/src/components/JhDescriptions/JhDescriptions.md +724 -0
- package/src/components/JhDescriptions/JhDescriptions.stories.js +858 -0
- package/src/components/JhDescriptions/JhDescriptions.vue +933 -0
- package/src/components/JhDraggable/JhDraggable.md +66 -0
- package/src/components/JhDraggable/JhDraggable.stories.js +161 -0
- package/src/components/JhDraggable/JhDraggable.vue +254 -0
- package/src/components/JhDrawer/JhDrawer.md +68 -0
- package/src/components/JhDrawer/JhDrawer.stories.js +478 -0
- package/src/components/JhDrawer/JhDrawer.vue +281 -0
- package/src/components/JhDrawerForm/JhDrawerForm.md +69 -0
- package/src/components/JhDrawerForm/JhDrawerForm.stories.js +492 -0
- package/src/components/JhDrawerForm/JhDrawerForm.vue +297 -0
- package/src/components/JhEditableTable/JhEditableTable.md +507 -0
- package/src/components/JhEditableTable/JhEditableTable.stories.js +615 -0
- package/src/components/JhEditableTable/JhEditableTable.vue +685 -0
- package/src/components/JhFileInput/JhFileInput.md +56 -0
- package/src/components/JhFileInput/JhFileInput.stories.js +103 -0
- package/src/components/JhFileInput/JhFileInput.vue +253 -0
- package/src/components/JhForm/JhForm.md +676 -0
- package/src/components/JhForm/JhForm.stories.js +1375 -0
- package/src/components/JhForm/JhForm.vue +657 -0
- package/src/components/JhFormField/JhFormField.stories.js +217 -0
- package/src/components/JhFormField/JhFormField.vue +439 -0
- package/src/components/JhFormFields/JhFormFields.md +647 -0
- package/src/components/JhFormFields/JhFormFields.stories.js +922 -0
- package/src/components/JhFormFields/JhFormFields.vue +998 -0
- package/src/components/JhFormList/JhFormList.md +303 -0
- package/src/components/JhFormList/JhFormList.stories.js +661 -0
- package/src/components/JhFormList/JhFormList.vue +1127 -0
- package/src/components/JhJsonEditor/JhJsonEditor.md +54 -0
- package/src/components/JhJsonEditor/JhJsonEditor.stories.js +157 -0
- package/src/components/JhJsonEditor/JhJsonEditor.vue +178 -0
- package/src/components/JhLayout/JhLayout.md +580 -0
- package/src/components/JhLayout/JhLayout.stories.js +414 -0
- package/src/components/JhLayout/JhLayout.vue +387 -0
- package/src/components/JhList/JhList.md +441 -0
- package/src/components/JhList/JhList.stories.js +524 -0
- package/src/components/JhList/JhList.vue +571 -0
- package/src/components/JhMarkdownEditor/JhMarkdownEditor.md +56 -0
- package/src/components/JhMarkdownEditor/JhMarkdownEditor.stories.js +191 -0
- package/src/components/JhMarkdownEditor/JhMarkdownEditor.vue +188 -0
- package/src/components/JhMask/JhMask.md +62 -0
- package/src/components/JhMask/JhMask.stories.js +270 -0
- package/src/components/JhMask/JhMask.vue +123 -0
- package/src/components/JhMenu/JhMenu.md +85 -0
- package/src/components/JhMenu/JhMenu.stories.js +384 -0
- package/src/components/JhMenu/JhMenu.vue +545 -0
- package/src/components/JhModal/JhModal.md +68 -0
- package/src/components/JhModal/JhModal.stories.js +562 -0
- package/src/components/JhModal/JhModal.vue +235 -0
- package/src/components/JhModalForm/JhModalForm.md +69 -0
- package/src/components/JhModalForm/JhModalForm.stories.js +592 -0
- package/src/components/JhModalForm/JhModalForm.vue +298 -0
- package/src/components/JhPageContainer/JhPageContainer.md +409 -0
- package/src/components/JhPageContainer/JhPageContainer.stories.js +209 -0
- package/src/components/JhPageContainer/JhPageContainer.vue +72 -0
- package/src/components/JhQueryFilter/JhQueryFilter.md +77 -0
- package/src/components/JhQueryFilter/JhQueryFilter.stories.js +684 -0
- package/src/components/JhQueryFilter/JhQueryFilter.vue +429 -0
- package/src/components/JhScene/JhScene.md +64 -0
- package/src/components/JhScene/JhScene.stories.js +317 -0
- package/src/components/JhScene/JhScene.vue +376 -0
- package/src/components/JhStatisticCard/JhStatisticCard.md +363 -0
- package/src/components/JhStatisticCard/JhStatisticCard.stories.js +847 -0
- package/src/components/JhStatisticCard/JhStatisticCard.vue +459 -0
- package/src/components/JhStepsForm/JhStepsForm.md +666 -0
- package/src/components/JhStepsForm/JhStepsForm.stories.js +1224 -0
- package/src/components/JhStepsForm/JhStepsForm.vue +749 -0
- package/src/components/JhTable/JhTable.md +730 -0
- package/src/components/JhTable/JhTable.stories.js +1444 -0
- package/src/components/JhTable/JhTable.vue +2298 -0
- package/src/components/JhTableAttachment/JhTableAttachment.md +70 -0
- package/src/components/JhTableAttachment/JhTableAttachment.stories.js +198 -0
- package/src/components/JhTableAttachment/JhTableAttachment.vue +264 -0
- package/src/components/JhToast/JhToast.md +67 -0
- package/src/components/JhToast/JhToast.stories.js +386 -0
- package/src/components/JhToast/JhToast.vue +239 -0
- package/src/components/JhTreeSelect/JhTreeSelect.md +82 -0
- package/src/components/JhTreeSelect/JhTreeSelect.stories.js +391 -0
- package/src/components/JhTreeSelect/JhTreeSelect.vue +727 -0
- package/src/components/JhWaterMark/JhWaterMark.md +190 -0
- package/src/components/JhWaterMark/JhWaterMark.stories.js +675 -0
- package/src/components/JhWaterMark/JhWaterMark.vue +351 -0
- package/src/components/README.md +52 -0
- package/src/index.js +135 -0
- package/src/style/globalCSSJHV4.css +348 -0
- package/src/style/globalCSSVuetifyV4.css +637 -0
- package/src/style/storybook.css +4 -0
- package/src/tailwind.css +3 -0
- package/src/utils/vuetify.js +31 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# JhFormList 组件
|
|
2
|
+
|
|
3
|
+
基于 Ant Design ProFormList 设计的动态表单列表组件,支持动态增删改查表单项列表。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
### 核心功能
|
|
8
|
+
- ✅ **多种渲染模式**: Card、Table、Inline 三种展示模式
|
|
9
|
+
- ✅ **动态列表管理**: 支持新增、删除、排序、复制列表项
|
|
10
|
+
- ✅ **拖拽排序**: 可选的拖拽重排功能(需引入 SortableJS)
|
|
11
|
+
- ✅ **完整验证支持**: 列表级和项级验证
|
|
12
|
+
- ✅ **嵌套表单能力**: 每个列表项可包含多个字段或嵌套子列表
|
|
13
|
+
|
|
14
|
+
### ProFormList 风格特性
|
|
15
|
+
- ✅ **可折叠卡片**: 支持折叠/展开列表项(Card 模式)
|
|
16
|
+
- ✅ **操作守卫**: 添加/删除前的确认机制
|
|
17
|
+
- ✅ **创建按钮配置**: 灵活的按钮配置(creatorButtonProps)
|
|
18
|
+
- ✅ **自定义操作渲染**: actionRender 自定义操作按钮
|
|
19
|
+
- ✅ **数量限制提示**: 自动显示最大/最小数量限制提示
|
|
20
|
+
- ✅ **删除后回调**: onAfterRemove 回调支持
|
|
21
|
+
|
|
22
|
+
## 基础用法
|
|
23
|
+
|
|
24
|
+
```vue
|
|
25
|
+
<template>
|
|
26
|
+
<jh-form-list
|
|
27
|
+
v-model="contacts"
|
|
28
|
+
:fields="contactFields"
|
|
29
|
+
title="联系人列表"
|
|
30
|
+
description="请填写至少一位联系人信息"
|
|
31
|
+
:min="1"
|
|
32
|
+
:max="5"
|
|
33
|
+
/>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script>
|
|
37
|
+
export default {
|
|
38
|
+
data() {
|
|
39
|
+
return {
|
|
40
|
+
contacts: [
|
|
41
|
+
{ name: '张三', phone: '13800138000', email: 'zhang@example.com' }
|
|
42
|
+
],
|
|
43
|
+
contactFields: [
|
|
44
|
+
{ key: 'name', label: '姓名', type: 'text', required: true, cols: 4 },
|
|
45
|
+
{ key: 'phone', label: '电话', type: 'text', cols: 4 },
|
|
46
|
+
{ key: 'email', label: '邮箱', type: 'text', cols: 4 },
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
</script>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 渲染模式
|
|
55
|
+
|
|
56
|
+
### Card 模式(默认)
|
|
57
|
+
适用于字段较多、结构复杂的表单项。
|
|
58
|
+
|
|
59
|
+
```vue
|
|
60
|
+
<jh-form-list
|
|
61
|
+
v-model="items"
|
|
62
|
+
:fields="fields"
|
|
63
|
+
mode="card"
|
|
64
|
+
:collapsible="true"
|
|
65
|
+
:default-collapsed="false"
|
|
66
|
+
/>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Table 模式
|
|
70
|
+
适用于字段较少、需要对比数据的场景。
|
|
71
|
+
|
|
72
|
+
```vue
|
|
73
|
+
<jh-form-list
|
|
74
|
+
v-model="items"
|
|
75
|
+
:fields="fields"
|
|
76
|
+
mode="table"
|
|
77
|
+
:sortable="true"
|
|
78
|
+
:show-index="true"
|
|
79
|
+
/>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Inline 模式
|
|
83
|
+
适用于单字段或极简场景(如标签列表)。
|
|
84
|
+
|
|
85
|
+
```vue
|
|
86
|
+
<jh-form-list
|
|
87
|
+
v-model="tags"
|
|
88
|
+
:fields="[{ key: 'name', label: '标签' }]"
|
|
89
|
+
mode="inline"
|
|
90
|
+
:inline-display-key="name"
|
|
91
|
+
/>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 高级功能
|
|
95
|
+
|
|
96
|
+
### 操作守卫
|
|
97
|
+
```vue
|
|
98
|
+
<jh-form-list
|
|
99
|
+
v-model="items"
|
|
100
|
+
:fields="fields"
|
|
101
|
+
:action-guard="{
|
|
102
|
+
beforeAddRow: async (count) => {
|
|
103
|
+
return await confirmAdd();
|
|
104
|
+
},
|
|
105
|
+
beforeRemoveRow: async (index, item) => {
|
|
106
|
+
return await confirmDelete(item);
|
|
107
|
+
}
|
|
108
|
+
}"
|
|
109
|
+
:on-after-remove="handleAfterRemove"
|
|
110
|
+
/>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 自定义创建按钮
|
|
114
|
+
```vue
|
|
115
|
+
<jh-form-list
|
|
116
|
+
v-model="items"
|
|
117
|
+
:fields="fields"
|
|
118
|
+
:creator-button-props="{
|
|
119
|
+
color: 'success',
|
|
120
|
+
text: '新增一行',
|
|
121
|
+
outlined: false,
|
|
122
|
+
large: true
|
|
123
|
+
}"
|
|
124
|
+
:creator-record="(index) => ({
|
|
125
|
+
id: Date.now(),
|
|
126
|
+
name: `项目${index + 1}`
|
|
127
|
+
})"
|
|
128
|
+
/>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 自定义操作按钮
|
|
132
|
+
```vue
|
|
133
|
+
<jh-form-list
|
|
134
|
+
v-model="items"
|
|
135
|
+
:fields="fields"
|
|
136
|
+
:action-render="({ item, index, removeItem, copyItem }) => {
|
|
137
|
+
return h('div', [
|
|
138
|
+
h('v-btn', {
|
|
139
|
+
props: { icon: true, small: true },
|
|
140
|
+
on: { click: () => copyItem() }
|
|
141
|
+
}, [h('v-icon', 'mdi-content-copy')]),
|
|
142
|
+
h('v-btn', {
|
|
143
|
+
props: { icon: true, small: true, color: 'error' },
|
|
144
|
+
on: { click: () => removeItem() }
|
|
145
|
+
}, [h('v-icon', 'mdi-delete')])
|
|
146
|
+
]);
|
|
147
|
+
}"
|
|
148
|
+
/>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 嵌套列表
|
|
152
|
+
```vue
|
|
153
|
+
<jh-form-list v-model="orders" :fields="orderFields">
|
|
154
|
+
<template #field-items="{ item, index, updateItem }">
|
|
155
|
+
<jh-form-list
|
|
156
|
+
:value="item.items"
|
|
157
|
+
:fields="itemFields"
|
|
158
|
+
@input="updateItem('items', $event)"
|
|
159
|
+
mode="table"
|
|
160
|
+
/>
|
|
161
|
+
</template>
|
|
162
|
+
</jh-form-list>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 列表验证
|
|
166
|
+
```vue
|
|
167
|
+
<jh-form-list
|
|
168
|
+
ref="formList"
|
|
169
|
+
v-model="items"
|
|
170
|
+
:fields="fields"
|
|
171
|
+
:rules="[
|
|
172
|
+
(items) => items.length >= 2 || '至少需要两项',
|
|
173
|
+
(items) => {
|
|
174
|
+
const names = items.map(i => i.name);
|
|
175
|
+
const unique = new Set(names);
|
|
176
|
+
return names.length === unique.size || '姓名不能重复';
|
|
177
|
+
}
|
|
178
|
+
]"
|
|
179
|
+
/>
|
|
180
|
+
|
|
181
|
+
<script>
|
|
182
|
+
methods: {
|
|
183
|
+
async validate() {
|
|
184
|
+
const isValid = await this.$refs.formList.validate();
|
|
185
|
+
if (isValid) {
|
|
186
|
+
// 提交数据
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
</script>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## API
|
|
194
|
+
|
|
195
|
+
### Props
|
|
196
|
+
|
|
197
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
198
|
+
|------|------|--------|------|
|
|
199
|
+
| value (v-model) | Array | `[]` | 列表数据 |
|
|
200
|
+
| fields | Array | `[]` | 字段配置数组 |
|
|
201
|
+
| mode | String | `'card'` | 渲染模式: `card` \| `table` \| `inline` |
|
|
202
|
+
| title | String | `''` | 列表标题 |
|
|
203
|
+
| description | String | `''` | 列表说明文字 |
|
|
204
|
+
| min | Number | `0` | 最小项数 |
|
|
205
|
+
| max | Number | `Infinity` | 最大项数 |
|
|
206
|
+
| sortable | Boolean | `false` | 是否启用拖拽排序 |
|
|
207
|
+
| copyable | Boolean | `true` | 是否显示复制按钮 |
|
|
208
|
+
| showIndex | Boolean | `true` | 是否显示序号 |
|
|
209
|
+
| showItemActions | Boolean | `true` | 是否显示项操作按钮 |
|
|
210
|
+
| defaultValue | Object/Function | `{}` | 新增项的默认值 |
|
|
211
|
+
| addButtonText | String | `'添加'` | 添加按钮文本 |
|
|
212
|
+
| addButtonProps | Object | `{}` | 添加按钮的 props |
|
|
213
|
+
| deleteConfirm | Boolean | `false` | 删除时是否需要确认 |
|
|
214
|
+
| deleteConfirmText | String | `'确定要删除这一项吗?'` | 删除确认文本 |
|
|
215
|
+
| itemLayout | String | `'horizontal'` | 列表项内表单布局 |
|
|
216
|
+
| itemLabelWidth | Number/String | `'auto'` | 列表项标签宽度 |
|
|
217
|
+
| dense | Boolean | `true` | 紧凑模式 |
|
|
218
|
+
| outlined | Boolean | `true` | 使用边框样式 |
|
|
219
|
+
| disabled | Boolean | `false` | 禁用整个列表 |
|
|
220
|
+
| readonly | Boolean | `false` | 只读模式 |
|
|
221
|
+
| rules | Array | `[]` | 列表级验证规则 |
|
|
222
|
+
| **alwaysShowItemLabel** | Boolean | `true` | 始终显示项标签 |
|
|
223
|
+
| **collapsible** | Boolean | `false` | 卡片是否可折叠 |
|
|
224
|
+
| **defaultCollapsed** | Boolean | `false` | 默认折叠状态 |
|
|
225
|
+
| **creatorButtonProps** | Object/Boolean | `{}` | 创建按钮配置,false 时隐藏 |
|
|
226
|
+
| **creatorRecord** | Object/Function | `null` | 创建记录的初始值 |
|
|
227
|
+
| **actionGuard** | Object | `{}` | 操作守卫配置 |
|
|
228
|
+
| **onAfterRemove** | Function | `null` | 删除后回调 |
|
|
229
|
+
| **actionRender** | Function | `null` | 自定义操作按钮渲染 |
|
|
230
|
+
| **maxLimitText** | String | `'已达到最大数量限制'` | 最大数量提示文本 |
|
|
231
|
+
| **minLimitText** | String | `'已达到最小数量限制'` | 最小数量提示文本 |
|
|
232
|
+
|
|
233
|
+
### Events
|
|
234
|
+
|
|
235
|
+
| 事件名 | 参数 | 说明 |
|
|
236
|
+
|--------|------|------|
|
|
237
|
+
| input | `(value: Array)` | v-model 更新事件 |
|
|
238
|
+
| change | `(value: Array)` | 列表数据变化 |
|
|
239
|
+
| add | `(item: Object, index: Number)` | 添加项后触发 |
|
|
240
|
+
| remove | `(item: Object, index: Number)` | 删除项后触发 |
|
|
241
|
+
| copy | `(item: Object, newItem: Object)` | 复制项后触发 |
|
|
242
|
+
| sort | `(oldIndex: Number, newIndex: Number)` | 排序后触发 |
|
|
243
|
+
| item-change | `(index: Number, item: Object)` | 单项数据变化 |
|
|
244
|
+
| validate | `(isValid: Boolean, errors: Object)` | 验证完成 |
|
|
245
|
+
| max-limit | `(max: Number)` | 达到最大数量限制 |
|
|
246
|
+
| min-limit | `(min: Number)` | 达到最小数量限制 |
|
|
247
|
+
|
|
248
|
+
### Methods
|
|
249
|
+
|
|
250
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
251
|
+
|--------|------|--------|------|
|
|
252
|
+
| addItem | `(item?: Object, index?: Number)` | `void` | 添加一项 |
|
|
253
|
+
| removeItem | `(index: Number)` | `void` | 删除指定项 |
|
|
254
|
+
| copyItem | `(index: Number)` | `void` | 复制指定项 |
|
|
255
|
+
| moveItem | `(oldIndex: Number, newIndex: Number)` | `void` | 移动项位置 |
|
|
256
|
+
| getItems | - | `Array` | 获取列表数据 |
|
|
257
|
+
| setItems | `(items: Array)` | `void` | 设置列表数据 |
|
|
258
|
+
| getItemValue | `(index: Number)` | `Object` | 获取指定项数据 |
|
|
259
|
+
| setItemValue | `(index: Number, value: Object)` | `void` | 设置指定项数据 |
|
|
260
|
+
| validate | - | `Promise<Boolean>` | 验证整个列表 |
|
|
261
|
+
| validateItem | `(index: Number)` | `Promise<Boolean>` | 验证指定项 |
|
|
262
|
+
| resetValidation | - | `void` | 重置验证状态 |
|
|
263
|
+
| reset | - | `void` | 重置列表为初始值 |
|
|
264
|
+
|
|
265
|
+
### Slots
|
|
266
|
+
|
|
267
|
+
| 插槽名 | 参数 | 说明 |
|
|
268
|
+
|--------|------|------|
|
|
269
|
+
| header | - | 自定义列表头部 |
|
|
270
|
+
| item | `{ item, index, fields, updateItem }` | 自定义列表项内容 |
|
|
271
|
+
| item-actions | `{ item, index, removeItem, copyItem }` | 自定义列表项操作区 |
|
|
272
|
+
| footer | `{ addItem, canAdd }` | 自定义列表底部 |
|
|
273
|
+
| empty | - | 空列表占位内容 |
|
|
274
|
+
| field-{key} | `{ item, index, field, updateItem }` | 自定义指定字段渲染 |
|
|
275
|
+
|
|
276
|
+
## 样式定制
|
|
277
|
+
|
|
278
|
+
```scss
|
|
279
|
+
// 自定义样式
|
|
280
|
+
.jh-form-list {
|
|
281
|
+
--jh-form-list-item-margin: 16px;
|
|
282
|
+
--jh-form-list-card-padding: 16px;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// 自定义卡片样式
|
|
286
|
+
.jh-form-list-item--card {
|
|
287
|
+
border-radius: 8px;
|
|
288
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## 注意事项
|
|
293
|
+
|
|
294
|
+
1. **拖拽排序**: 需要全局引入 SortableJS 库
|
|
295
|
+
2. **性能优化**: 大列表(100+ 项)建议使用 Table 模式
|
|
296
|
+
3. **嵌套列表**: 注意数据同步,使用 updateItem 方法更新
|
|
297
|
+
4. **验证规则**: 列表级规则和项级规则可以同时使用
|
|
298
|
+
|
|
299
|
+
## 相关组件
|
|
300
|
+
|
|
301
|
+
- [JhForm](../JhForm/JhForm.md) - 表单组件
|
|
302
|
+
- [JhFormFields](../JhFormFields/JhFormFields.md) - 表单字段组件
|
|
303
|
+
- [JhEditableTable](../JhEditableTable/JhEditableTable.md) - 可编辑表格组件
|