@aspire-ui/element-component-pro 1.0.26 → 1.0.27
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/dist/ProTableForm/CellEditor.vue.d.ts +5 -1
- package/dist/element-component-pro.es.js +447 -445
- package/dist/element-component-pro.es.js.map +1 -1
- package/dist/element-component-pro.umd.js +2 -2
- package/dist/element-component-pro.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +16 -11
- package/docs/CollapseContainer.md +100 -0
- package/docs/ComponentSetting.md +113 -0
- package/docs/ProDescriptions.md +215 -0
- package/docs/ProForm.md +879 -0
- package/docs/ProTable-Redesign.md +214 -0
- package/docs/ProTable.md +556 -0
- package/docs/ProTableForm.md +207 -0
- package/docs/image.png +0 -0
- package/package.json +3 -2
- package/src/CollapseContainer/CollapseContainer.vue +1 -1
- package/src/ProDescriptions/ProDescriptions.vue +1 -1
- package/src/ProForm/FormActions.vue +1 -1
- package/src/ProForm/ProForm.vue +1 -1
- package/src/ProForm/ProFormItem.vue +1 -1
- package/src/ProForm/TreeSelect.vue +1 -1
- package/src/ProTable/ProTable.vue +1 -1
- package/src/ProTable/TableAction.vue +1 -1
- package/src/ProTableForm/CellEditor.vue +15 -11
- package/src/ProTableForm/ProTableForm.vue +3 -2
- package/src/types/index.ts +17 -11
package/docs/ProForm.md
ADDED
|
@@ -0,0 +1,879 @@
|
|
|
1
|
+
# ProForm 表单组件
|
|
2
|
+
|
|
3
|
+
基于 Element UI Form 的二次封装,参考 [Vben Admin Form](https://doc.vvbin.cn/components/form.html),支持 Schema 驱动、useForm、render/slot、动态显示等能力。
|
|
4
|
+
|
|
5
|
+
## 组件构成
|
|
6
|
+
|
|
7
|
+
- **ProForm** - 主表单组件
|
|
8
|
+
- **ProFormItem** - 表单项(按 schema 自动渲染)
|
|
9
|
+
- **FormActions** - 提交/重置/展开按钮组(可单独使用)
|
|
10
|
+
|
|
11
|
+
## 基础用法
|
|
12
|
+
|
|
13
|
+
通过 `schemas` 配置表单项,支持 `input`、`select`、`api-select`、`tree-select`、`date-picker`、`switch` 等组件类型。
|
|
14
|
+
|
|
15
|
+
```vue
|
|
16
|
+
<template>
|
|
17
|
+
<ProForm
|
|
18
|
+
:schemas="schemas"
|
|
19
|
+
:initial-values="{ name: '' }"
|
|
20
|
+
:base-col-props="{ span: 8 }"
|
|
21
|
+
@submit="handleSubmit"
|
|
22
|
+
/>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
import { ProForm } from 'element-component-pro'
|
|
27
|
+
import type { ProFormSchema } from 'element-component-pro'
|
|
28
|
+
|
|
29
|
+
const schemas: ProFormSchema[] = [
|
|
30
|
+
{ field: 'name', label: '姓名', component: 'input', required: true, colProps: { span: 8 } },
|
|
31
|
+
{
|
|
32
|
+
field: 'status',
|
|
33
|
+
label: '状态',
|
|
34
|
+
component: 'select',
|
|
35
|
+
componentProps: {
|
|
36
|
+
options: [
|
|
37
|
+
{ label: '启用', value: 1 },
|
|
38
|
+
{ label: '禁用', value: 0 },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
colProps: { span: 8 },
|
|
42
|
+
},
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
const handleSubmit = (values: Record<string, unknown>) => {
|
|
46
|
+
console.log(values)
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## useForm 方式
|
|
52
|
+
|
|
53
|
+
通过 `useForm` 传入 formProps,支持编程式调用表单方法。**参数 props 内的值可以是 computed 或 ref 类型**。
|
|
54
|
+
|
|
55
|
+
```vue
|
|
56
|
+
<template>
|
|
57
|
+
<ProForm @register="register" @submit="handleSubmit" />
|
|
58
|
+
</template>
|
|
59
|
+
|
|
60
|
+
<script setup lang="ts">
|
|
61
|
+
import { ProForm, useForm } from 'element-component-pro'
|
|
62
|
+
|
|
63
|
+
const [register, formActions] = useForm({
|
|
64
|
+
schemas: [...],
|
|
65
|
+
labelWidth: '120px',
|
|
66
|
+
actionColOptions: { span: 24 },
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
// 响应式 props
|
|
70
|
+
const formProps = ref({ schemas: [...], disabled: false })
|
|
71
|
+
const [register2] = useForm(formProps)
|
|
72
|
+
|
|
73
|
+
const handleSubmit = (values: Record<string, unknown>) => {
|
|
74
|
+
console.log(values)
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 自定义 component
|
|
80
|
+
|
|
81
|
+
`schema.component` 除内置类型外,支持**自定义组件**,有两种用法:
|
|
82
|
+
|
|
83
|
+
### 1. 组件名 + components 映射
|
|
84
|
+
|
|
85
|
+
在 ProForm 上传入 `components`,schema 中 `component` 填组件名字符串,会从 `components` 中解析;若未找到则当作全局注册的组件名。
|
|
86
|
+
|
|
87
|
+
```vue
|
|
88
|
+
<template>
|
|
89
|
+
<ProForm :schemas="schemas" :components="customComponents" @submit="handleSubmit" />
|
|
90
|
+
</template>
|
|
91
|
+
|
|
92
|
+
<script setup lang="ts">
|
|
93
|
+
import { ProForm } from 'element-component-pro'
|
|
94
|
+
import type { ProFormSchema } from 'element-component-pro'
|
|
95
|
+
import MyRate from './MyRate.vue'
|
|
96
|
+
|
|
97
|
+
const customComponents = { MyRate }
|
|
98
|
+
|
|
99
|
+
const schemas: ProFormSchema[] = [
|
|
100
|
+
{ field: 'name', label: '姓名', component: 'input' },
|
|
101
|
+
{ field: 'score', label: '评分', component: 'MyRate', componentProps: { max: 5 } },
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
const handleSubmit = (values: Record<string, unknown>) => {
|
|
105
|
+
console.log(values)
|
|
106
|
+
}
|
|
107
|
+
</script>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 2. 内联组件(直接传组件定义)
|
|
111
|
+
|
|
112
|
+
`schema.component` 可直接传入 Vue 组件选项对象或构造函数,无需事先注册到 `components`。
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import Rate from './Rate.vue'
|
|
116
|
+
|
|
117
|
+
const schemas: ProFormSchema[] = [
|
|
118
|
+
{ field: 'score', label: '评分', component: Rate, componentProps: { max: 5 } },
|
|
119
|
+
]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**约定**:自定义组件需支持 `value`(或 `modelValue`)prop 与 `input` 事件,以与表单双向绑定;也可通过 `componentProps` 覆盖 `value` / `@input`。
|
|
123
|
+
|
|
124
|
+
## Props
|
|
125
|
+
|
|
126
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
127
|
+
|------|------|--------|------|
|
|
128
|
+
| schemas | `ProFormSchema[]` | - | 表单项配置 |
|
|
129
|
+
| modelValue | `Record<string, unknown>` | - | 受控表单值,支持 `v-model` 双向绑定 |
|
|
130
|
+
| initialValues | `Record<string, unknown>` | - | 初始值 |
|
|
131
|
+
| labelWidth | `string` | `'120px'` | 标签宽度 |
|
|
132
|
+
| labelPosition | `'left' \| 'right' \| 'top'` | `'right'` | 标签位置 |
|
|
133
|
+
| colon | `boolean` | `true` | 是否在 label 后显示冒号 |
|
|
134
|
+
| gutter | `number` | `24` | 栅格间距 |
|
|
135
|
+
| size | `'medium' \| 'small' \| 'large'` | `'medium'` | 尺寸 |
|
|
136
|
+
| disabled | `boolean` | `false` | 是否禁用 |
|
|
137
|
+
| baseColProps | `ColEx` | - | 全局栅格配置 |
|
|
138
|
+
| baseRowStyle | `Record<string, string \| number>` | - | 栅格行样式 |
|
|
139
|
+
| autoSetPlaceholder | `boolean` | `true` | 是否自动设置 placeholder |
|
|
140
|
+
| showSubmitButton | `boolean` | `true` | 是否显示提交按钮 |
|
|
141
|
+
| showResetButton | `boolean` | `true` | 是否显示重置按钮 |
|
|
142
|
+
| submitButtonText | `string` | `'提交'` | 提交按钮文字 |
|
|
143
|
+
| resetButtonText | `string` | `'重置'` | 重置按钮文字 |
|
|
144
|
+
| submitButtonIcon | `string` | `'el-icon-search'` | 提交按钮图标 |
|
|
145
|
+
| resetButtonIcon | `string` | `'el-icon-refresh-left'` | 重置按钮图标 |
|
|
146
|
+
| showActionButtonGroup | `boolean` | `true` | 是否显示操作按钮组 |
|
|
147
|
+
| actionColOptions | `ColEx` | 响应式配置 | 操作按钮区域栅格,支持 xs/sm/md/lg/xl |
|
|
148
|
+
| showAdvancedButton | `boolean` | `false` | 是否显示展开/收起按钮 |
|
|
149
|
+
| autoAdvancedLine | `number` | `3` | 超过指定行数默认折叠 |
|
|
150
|
+
| alwaysShowLines | `number` | `1` | 折叠时显示的行数 |
|
|
151
|
+
| submitFunc | `() => Promise<void>` | - | 自定义提交逻辑 |
|
|
152
|
+
| resetFunc | `() => Promise<void>` | - | 自定义重置逻辑 |
|
|
153
|
+
| submitOnReset | `boolean` | `false` | 重置时是否提交 |
|
|
154
|
+
| fieldMapToTime | `FieldMapToTime[]` | - | 时间范围字段映射 |
|
|
155
|
+
| formListeners | `FormListeners` | - | 透传给 el-form 的事件监听器 |
|
|
156
|
+
| components | `Record<string, unknown>` | - | 自定义组件映射(组件名 -> 组件),供 schema.component 使用 |
|
|
157
|
+
|
|
158
|
+
## ProFormSchema
|
|
159
|
+
|
|
160
|
+
| 属性 | 类型 | 说明 |
|
|
161
|
+
|------|------|------|
|
|
162
|
+
| field | `string` | 字段名 |
|
|
163
|
+
| label | `string` | 标签 |
|
|
164
|
+
| labelWidth | `string` | 当前表单项标签宽度,配置后可覆盖 ProForm 的 `labelWidth` |
|
|
165
|
+
| colon | `boolean` | 当前表单项是否显示 label 冒号,优先级高于 ProForm 的 `colon` |
|
|
166
|
+
| component | `string \| object \| Function` | 组件类型:input、select、**api-select**、**tree-select**、date-picker、date-range、input-number、**formatted-number**、switch、cascader、checkbox、radio;或自定义组件名(ProForm components/全局注册);或内联组件(Vue 组件选项/构造函数) |
|
|
167
|
+
| componentProps | `object \| function` | 组件属性,支持对象或函数,详见 [componentProps 详解](#componentprops-详解) |
|
|
168
|
+
| placeholder | `string` | 占位符 |
|
|
169
|
+
| defaultValue | `unknown` | 默认值 |
|
|
170
|
+
| required | `boolean` | 是否必填 |
|
|
171
|
+
| rules | `Array` | 校验规则 |
|
|
172
|
+
| colProps | `ColEx` | 栅格配置,支持 span、xs、sm、md、lg、xl 等响应式断点 |
|
|
173
|
+
| hidden | `boolean` | 是否隐藏 |
|
|
174
|
+
| render | `(params) => VNode \| string` | 自定义渲染 |
|
|
175
|
+
| slot | `string` | 具名插槽名称 |
|
|
176
|
+
| show | `boolean \| (params) => boolean` | 动态显示(CSS 控制) |
|
|
177
|
+
| ifShow | `boolean \| (params) => boolean` | 动态显示(不渲染 DOM) |
|
|
178
|
+
| dynamicDisabled | `boolean \| (params) => boolean` | 动态禁用 |
|
|
179
|
+
| dynamicRules | `Array \| (params) => Array` | 动态校验规则 |
|
|
180
|
+
| helpMessage | `string \| string[]` | 标签右侧温馨提示 |
|
|
181
|
+
| helpComponentProps | `object` | 温馨提示组件 props |
|
|
182
|
+
| tooltip | `boolean \| string \| object \| (params) => boolean \| string \| object` | 表单项 value tooltip,`true` 时默认展示当前值 |
|
|
183
|
+
|
|
184
|
+
### ColEx 栅格配置
|
|
185
|
+
|
|
186
|
+
`colProps`、`baseColProps`、`actionColOptions` 均支持响应式断点,与 Element UI 一致:
|
|
187
|
+
|
|
188
|
+
| 断点 | 视口宽度 |
|
|
189
|
+
|------|----------|
|
|
190
|
+
| xs | <768px |
|
|
191
|
+
| sm | ≥768px |
|
|
192
|
+
| md | ≥992px |
|
|
193
|
+
| lg | ≥1200px |
|
|
194
|
+
| xl | ≥1920px |
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
// 响应式栅格示例
|
|
198
|
+
baseColProps: { xs: 24, sm: 12, md: 8, lg: 6 }
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## useForm 方法
|
|
202
|
+
|
|
203
|
+
| 方法 | 类型 | 说明 |
|
|
204
|
+
|------|------|------|
|
|
205
|
+
| getFieldsValue | `() => Record<string, unknown>` | 获取表单值 |
|
|
206
|
+
| setFieldsValue | `(values) => Promise<void>` | 设置表单字段值 |
|
|
207
|
+
| resetFields | `() => Promise<void>` | 重置表单 |
|
|
208
|
+
| validate | `(nameList?) => Promise<unknown>` | 校验整个表单 |
|
|
209
|
+
| validateFields | `(nameList?) => Promise<unknown>` | 校验指定表单项 |
|
|
210
|
+
| submit | `() => Promise<void>` | 提交表单 |
|
|
211
|
+
| scrollToField | `(name, options?) => Promise<void>` | 滚动到对应字段 |
|
|
212
|
+
| clearValidate | `(name?) => void` | 清空校验 |
|
|
213
|
+
| updateSchema | `(data) => Promise<void>` | 更新 schema |
|
|
214
|
+
| appendSchemaByField | `(schema, prefixField?, first?) => Promise<void>` | 插入 schema |
|
|
215
|
+
| removeSchemaByField | `(field) => Promise<void>` | 删除 schema |
|
|
216
|
+
| setProps | `(props) => Promise<void>` | 设置表单 Props |
|
|
217
|
+
| getComponentInstance | `(field) => ComponentPublicInstance \| null` | 获取指定字段的组件实例 |
|
|
218
|
+
| getFieldOptions | `(field, raw?) => Array<{ label: string; value: unknown }> \| unknown[]` | 获取 `api-select` 字段的 options;`raw = true` 时返回接口原始列表数据 |
|
|
219
|
+
| isFieldLoading | `(field) => boolean` | 获取 `api-select` 字段的加载状态 |
|
|
220
|
+
|
|
221
|
+
## Slots
|
|
222
|
+
|
|
223
|
+
| 名称 | 说明 |
|
|
224
|
+
|------|------|
|
|
225
|
+
| formHeader | 表单顶部区域 |
|
|
226
|
+
| formFooter | 表单底部区域 |
|
|
227
|
+
| submitBefore | 提交按钮前 |
|
|
228
|
+
| resetBefore | 重置按钮前 |
|
|
229
|
+
| advanceBefore | 展开/收起按钮前 |
|
|
230
|
+
| advanceAfter | 展开/收起按钮后 |
|
|
231
|
+
| actions | 操作按钮区域(在展开/收起按钮后) |
|
|
232
|
+
| [schema.field] / [schema.slot] | 自定义表单项内容 |
|
|
233
|
+
|
|
234
|
+
操作按钮顺序:**提交 → 重置 → 展开/收起 → 自定义操作**。表单项与操作按钮在同一行,操作按钮右对齐。
|
|
235
|
+
|
|
236
|
+
**展开/收起**:当 `showAdvancedButton` 且字段数超过 `alwaysShowLines` 行可容纳数量时显示。`hasMoreFields` 会根据当前视口宽度和 `colProps` 的响应式断点(xs/sm/md/lg/xl)动态计算。
|
|
237
|
+
|
|
238
|
+
## 示例
|
|
239
|
+
|
|
240
|
+
### v-model / modelValue
|
|
241
|
+
|
|
242
|
+
`ProForm` 支持通过 `v-model` 进行受控绑定。传入 `modelValue` 后,表单项变更、`setFieldsValue()`、`resetFields()` 都会触发 `update:modelValue`。
|
|
243
|
+
|
|
244
|
+
`initialValues` 只用于补齐缺失字段,不会覆盖 `modelValue` 中已经存在的值。
|
|
245
|
+
|
|
246
|
+
```vue
|
|
247
|
+
<template>
|
|
248
|
+
<ProForm
|
|
249
|
+
v-model="formData"
|
|
250
|
+
:schemas="schemas"
|
|
251
|
+
:initial-values="{ status: 0, remark: '默认备注' }"
|
|
252
|
+
@submit="handleSubmit"
|
|
253
|
+
/>
|
|
254
|
+
</template>
|
|
255
|
+
|
|
256
|
+
<script setup lang="ts">
|
|
257
|
+
import { ref } from 'vue'
|
|
258
|
+
import type { ProFormSchema } from 'element-component-pro'
|
|
259
|
+
|
|
260
|
+
const formData = ref({
|
|
261
|
+
name: '张三',
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
const schemas: ProFormSchema[] = [
|
|
265
|
+
{ field: 'name', label: '姓名', component: 'input' },
|
|
266
|
+
{ field: 'status', label: '状态', component: 'select', defaultValue: 1, componentProps: {
|
|
267
|
+
options: [
|
|
268
|
+
{ label: '启用', value: 1 },
|
|
269
|
+
{ label: '禁用', value: 0 },
|
|
270
|
+
],
|
|
271
|
+
} },
|
|
272
|
+
{ field: 'remark', label: '备注', component: 'input' },
|
|
273
|
+
]
|
|
274
|
+
|
|
275
|
+
const handleSubmit = (values: Record<string, unknown>) => {
|
|
276
|
+
console.log(values)
|
|
277
|
+
}
|
|
278
|
+
</script>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
上例初始化后的值为:`name` 使用 `modelValue` 中的 `'张三'`,`status` 补 `defaultValue: 1`,`remark` 补 `initialValues.remark`。
|
|
282
|
+
|
|
283
|
+
调用 `resetFields()` 或点击重置按钮时,也会按同样规则重建值:优先保留当前外部显式传入的字段,其余字段按 `defaultValue`、`initialValues` 补齐,并触发 `update:modelValue`。
|
|
284
|
+
|
|
285
|
+
### useForm + v-model
|
|
286
|
+
|
|
287
|
+
`useForm` 可以和 `v-model` 一起使用。此时 `setFieldsValue()`、`resetFields()` 等编程式方法同样会触发 `update:modelValue`,父组件拿到的仍然是统一的受控数据源。
|
|
288
|
+
|
|
289
|
+
```vue
|
|
290
|
+
<template>
|
|
291
|
+
<ProForm v-model="formData" @register="register" />
|
|
292
|
+
</template>
|
|
293
|
+
|
|
294
|
+
<script setup lang="ts">
|
|
295
|
+
import { ref } from 'vue'
|
|
296
|
+
import { useForm } from 'element-component-pro'
|
|
297
|
+
|
|
298
|
+
const formData = ref({ name: '张三' })
|
|
299
|
+
|
|
300
|
+
const [register, formActions] = useForm({
|
|
301
|
+
schemas,
|
|
302
|
+
modelValue: formData,
|
|
303
|
+
initialValues: { remark: '默认备注' },
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
const fillValues = () => {
|
|
307
|
+
formActions.setFieldsValue({ name: '李四' })
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const resetValues = () => {
|
|
311
|
+
formActions.resetFields()
|
|
312
|
+
}
|
|
313
|
+
</script>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### labelWidth
|
|
317
|
+
|
|
318
|
+
表单级 `labelWidth` 用于统一控制标签宽度;当某个字段需要更宽或更窄的标签区域时,可在该项 schema 上单独配置 `labelWidth`,其优先级高于 `ProForm` 的 `labelWidth`。
|
|
319
|
+
|
|
320
|
+
```vue
|
|
321
|
+
<template>
|
|
322
|
+
<ProForm :schemas="schemas" label-width="120px" />
|
|
323
|
+
</template>
|
|
324
|
+
|
|
325
|
+
<script setup lang="ts">
|
|
326
|
+
import type { ProFormSchema } from 'element-component-pro'
|
|
327
|
+
|
|
328
|
+
const schemas: ProFormSchema[] = [
|
|
329
|
+
{
|
|
330
|
+
field: 'name',
|
|
331
|
+
label: '姓名',
|
|
332
|
+
component: 'input',
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
field: 'identityCard',
|
|
336
|
+
label: '身份证号码',
|
|
337
|
+
component: 'input',
|
|
338
|
+
labelWidth: '160px',
|
|
339
|
+
},
|
|
340
|
+
]
|
|
341
|
+
</script>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### colon
|
|
345
|
+
|
|
346
|
+
`ProForm` 默认会在 label 后显示冒号,可通过表单级 `colon` 统一关闭,也可以在单个 schema 上单独覆盖。
|
|
347
|
+
|
|
348
|
+
```vue
|
|
349
|
+
<template>
|
|
350
|
+
<ProForm :schemas="schemas" :colon="false" />
|
|
351
|
+
</template>
|
|
352
|
+
|
|
353
|
+
<script setup lang="ts">
|
|
354
|
+
const schemas = [
|
|
355
|
+
{
|
|
356
|
+
field: 'name',
|
|
357
|
+
label: '姓名',
|
|
358
|
+
component: 'input',
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
field: 'status',
|
|
362
|
+
label: '状态',
|
|
363
|
+
component: 'select',
|
|
364
|
+
colon: true,
|
|
365
|
+
},
|
|
366
|
+
]
|
|
367
|
+
</script>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
规则如下:
|
|
371
|
+
|
|
372
|
+
- `ProForm` 默认 `colon: true`
|
|
373
|
+
- `schema.colon` 优先级高于 `ProForm.colon`
|
|
374
|
+
- 关闭后只影响 label 文案展示,不影响校验、helpMessage 和 tooltip
|
|
375
|
+
|
|
376
|
+
### helpMessage
|
|
377
|
+
|
|
378
|
+
```ts
|
|
379
|
+
{
|
|
380
|
+
field: 'name',
|
|
381
|
+
label: '姓名',
|
|
382
|
+
helpMessage: '请输入真实姓名',
|
|
383
|
+
// 或
|
|
384
|
+
helpMessage: ['提示1', '提示2'],
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### tooltip
|
|
389
|
+
|
|
390
|
+
`tooltip` 用于给表单项 value 增加悬浮提示,适合输入内容较长、需要补充说明或希望直接回显当前值的场景。
|
|
391
|
+
|
|
392
|
+
支持以下几种写法:
|
|
393
|
+
|
|
394
|
+
| 写法 | 说明 |
|
|
395
|
+
|------|------|
|
|
396
|
+
| `true` | 启用 tooltip,并默认使用当前字段值作为内容 |
|
|
397
|
+
| `string` | 使用固定文案作为 tooltip 内容 |
|
|
398
|
+
| `object` | 透传给 `el-tooltip` 的 props;未传 `content` 时默认使用当前字段值 |
|
|
399
|
+
| `(params) => ...` | 动态返回上面任一类型,适合根据其他字段联动 |
|
|
400
|
+
|
|
401
|
+
`params` 与 `render`、`show` 等回调保持一致,包含以下字段:
|
|
402
|
+
|
|
403
|
+
- `schema`:当前字段 schema
|
|
404
|
+
- `field`:当前字段名
|
|
405
|
+
- `model` / `values`:当前表单值
|
|
406
|
+
|
|
407
|
+
默认行为:
|
|
408
|
+
|
|
409
|
+
- 默认 `placement` 为 `top`
|
|
410
|
+
- 默认 `effect` 为 `dark`
|
|
411
|
+
- 当 tooltip 内容为空字符串、`null`、`undefined` 或空数组时,会自动禁用 tooltip
|
|
412
|
+
- 当传入数组值(如多选、级联)且未显式指定 `content` 时,会自动用逗号拼接后展示
|
|
413
|
+
|
|
414
|
+
```ts
|
|
415
|
+
{
|
|
416
|
+
field: 'name',
|
|
417
|
+
label: '姓名',
|
|
418
|
+
component: 'input',
|
|
419
|
+
tooltip: true, // 默认展示当前字段值
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
{
|
|
423
|
+
field: 'status',
|
|
424
|
+
label: '状态',
|
|
425
|
+
component: 'select',
|
|
426
|
+
tooltip: '请选择账号状态',
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
{
|
|
430
|
+
field: 'remark',
|
|
431
|
+
label: '备注',
|
|
432
|
+
component: 'input',
|
|
433
|
+
tooltip: ({ values }) => values.status === 0 ? '禁用状态下仅支持查看' : false,
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
{
|
|
437
|
+
field: 'address',
|
|
438
|
+
label: '地址',
|
|
439
|
+
component: 'input',
|
|
440
|
+
tooltip: {
|
|
441
|
+
placement: 'top-start',
|
|
442
|
+
effect: 'dark',
|
|
443
|
+
content: '请填写详细地址',
|
|
444
|
+
},
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
当传入对象且未显式指定 `content` 时,会默认使用当前字段值作为 tooltip 内容。
|
|
449
|
+
|
|
450
|
+
建议:
|
|
451
|
+
|
|
452
|
+
- 输入框、文本域、级联、多选这类“内容可能被遮挡或较长”的字段优先使用 `tooltip: true`
|
|
453
|
+
- 下拉、开关等语义明确的控件,更适合使用固定文案或函数式 tooltip 做补充说明
|
|
454
|
+
- 如果需要完全自定义展示内容,优先使用对象写法并显式传入 `content`
|
|
455
|
+
|
|
456
|
+
### tooltip 常见问题
|
|
457
|
+
|
|
458
|
+
#### 1. `tooltip: true` 显示的是什么?
|
|
459
|
+
|
|
460
|
+
默认显示当前字段的实际值:
|
|
461
|
+
|
|
462
|
+
- 普通输入值会转成字符串展示
|
|
463
|
+
- 多选、级联这类数组值会按逗号拼接展示
|
|
464
|
+
- 空值、`null`、`undefined`、空数组时不会显示 tooltip
|
|
465
|
+
|
|
466
|
+
#### 2. 对 `select` / `radio` / `checkbox` 会显示 label 还是 value?
|
|
467
|
+
|
|
468
|
+
当前默认显示的是字段真实值,而不是选项的 `label`。
|
|
469
|
+
|
|
470
|
+
如果你希望展示更友好的文案,建议使用函数或对象形式自行指定 `content`:
|
|
471
|
+
|
|
472
|
+
```ts
|
|
473
|
+
{
|
|
474
|
+
field: 'status',
|
|
475
|
+
label: '状态',
|
|
476
|
+
component: 'select',
|
|
477
|
+
componentProps: {
|
|
478
|
+
options: [
|
|
479
|
+
{ label: '启用', value: 1 },
|
|
480
|
+
{ label: '禁用', value: 0 },
|
|
481
|
+
],
|
|
482
|
+
},
|
|
483
|
+
tooltip: ({ values }) => values.status === 1 ? '当前为启用状态' : '当前为禁用状态',
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
#### 3. 我想自定义 tooltip 的位置、主题、延迟怎么办?
|
|
488
|
+
|
|
489
|
+
直接使用对象形式,透传 `el-tooltip` 的 props:
|
|
490
|
+
|
|
491
|
+
```ts
|
|
492
|
+
{
|
|
493
|
+
field: 'remark',
|
|
494
|
+
label: '备注',
|
|
495
|
+
component: 'input',
|
|
496
|
+
tooltip: {
|
|
497
|
+
placement: 'top-start',
|
|
498
|
+
effect: 'light',
|
|
499
|
+
openDelay: 300,
|
|
500
|
+
content: '请填写详细说明',
|
|
501
|
+
},
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
#### 4. 哪些场景更推荐开启 tooltip?
|
|
506
|
+
|
|
507
|
+
推荐优先用于以下字段:
|
|
508
|
+
|
|
509
|
+
- 长文本输入
|
|
510
|
+
- 多选结果较多
|
|
511
|
+
- 级联选择层级较深
|
|
512
|
+
- 需要补充业务解释的控件
|
|
513
|
+
|
|
514
|
+
如果字段本身语义很直观、值也很短,可以不必开启,避免交互噪音。
|
|
515
|
+
|
|
516
|
+
#### 5. tooltip 能不能根据其他字段动态变化?
|
|
517
|
+
|
|
518
|
+
可以,直接使用函数形式即可。该函数会拿到当前表单值,适合做联动说明:
|
|
519
|
+
|
|
520
|
+
```ts
|
|
521
|
+
{
|
|
522
|
+
field: 'email',
|
|
523
|
+
label: '邮箱',
|
|
524
|
+
component: 'input',
|
|
525
|
+
tooltip: ({ values }) => values.status === 0 ? '禁用状态下邮箱仅做展示' : false,
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### slot 自定义
|
|
530
|
+
|
|
531
|
+
```vue
|
|
532
|
+
<ProForm :schemas="schemas" @submit="handleSubmit">
|
|
533
|
+
<template #customField="{ model, field }">
|
|
534
|
+
<el-input v-model="model[field]" />
|
|
535
|
+
</template>
|
|
536
|
+
</ProForm>
|
|
537
|
+
|
|
538
|
+
// schemas
|
|
539
|
+
{ field: 'customField', label: '自定义', slot: 'customField' }
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### ifShow / dynamicDisabled
|
|
543
|
+
|
|
544
|
+
```ts
|
|
545
|
+
{
|
|
546
|
+
field: 'remark',
|
|
547
|
+
label: '备注',
|
|
548
|
+
ifShow: ({ values }) => !!values.status, // 仅当 status 有值时显示
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
field: 'email',
|
|
552
|
+
label: '邮箱',
|
|
553
|
+
dynamicDisabled: ({ values }) => values.status === 0, // status 为 0 时禁用
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
**注意**:当 `ifShow` 为 `false` 时,该字段不会出现在提交数据和 `getFieldsValue()` 的返回值中。
|
|
558
|
+
|
|
559
|
+
## componentProps 详解
|
|
560
|
+
|
|
561
|
+
`componentProps` 用于配置底层 Element UI 组件的属性,支持**对象**和**函数**两种形式,会透传给 `el-input`、`el-select`、`el-date-picker` 等组件。
|
|
562
|
+
|
|
563
|
+
### 对象形式
|
|
564
|
+
|
|
565
|
+
直接传入对象,适用于静态配置:
|
|
566
|
+
|
|
567
|
+
```ts
|
|
568
|
+
{
|
|
569
|
+
field: 'status',
|
|
570
|
+
label: '状态',
|
|
571
|
+
component: 'select',
|
|
572
|
+
componentProps: {
|
|
573
|
+
options: [
|
|
574
|
+
{ label: '启用', value: 1 },
|
|
575
|
+
{ label: '禁用', value: 0 },
|
|
576
|
+
],
|
|
577
|
+
clearable: true,
|
|
578
|
+
filterable: true,
|
|
579
|
+
},
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### api-select(接口下拉)
|
|
584
|
+
|
|
585
|
+
选项由接口动态拉取,适合字典、远程数据。在 schema 中设置 `component: 'api-select'`,并在 `componentProps` 中传入 `api`(及可选的 `labelField`、`valueField`):
|
|
586
|
+
|
|
587
|
+
```ts
|
|
588
|
+
{
|
|
589
|
+
field: 'status',
|
|
590
|
+
label: '状态',
|
|
591
|
+
component: 'api-select',
|
|
592
|
+
componentProps: {
|
|
593
|
+
api: () => api.getStatusList(), // 返回 Promise<{ label, value }[]> 或 Promise<{ list: [] }>
|
|
594
|
+
labelField: 'label', // 可选,默认 'label'
|
|
595
|
+
valueField: 'value', // 可选,默认 'value'
|
|
596
|
+
clearable: true,
|
|
597
|
+
filterable: true,
|
|
598
|
+
},
|
|
599
|
+
}
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
`api` 可声明为 `(params?: Record<string, unknown>) => Promise<...>`,会收到当前 `params`;传入 **params** 后,当 `params` 变化时会自动重新拉取 options(适合依赖其他表单项的联动下拉)。**lazy: true** 时改为懒加载:仅在展开下拉时请求,不在挂载时请求。**filterable: true** 时开启下拉内关键字搜索(在已加载的选项中做前端过滤,与 el-select 一致)。
|
|
603
|
+
|
|
604
|
+
`api` 返回值约定:直接为 `Array<{ label, value }>`,或为 `{ list: [] }` / `{ data: [] }`,列表项可为任意结构,通过 `labelField` / `valueField` 指定字段名。
|
|
605
|
+
|
|
606
|
+
### api-select 动态获取 Options
|
|
607
|
+
|
|
608
|
+
`api-select` 组件支持通过 `formActionType` 动态获取内部加载的 options 和 loading 状态,便于实现联动逻辑或展示辅助信息。
|
|
609
|
+
|
|
610
|
+
新增的 `FormActionType` 方法:
|
|
611
|
+
|
|
612
|
+
| 方法 | 说明 | 返回值 |
|
|
613
|
+
|------|------|--------|
|
|
614
|
+
| `getFieldOptions(field, raw?)` | 获取指定 `api-select` 字段的 options;`raw = true` 时返回接口原始列表数据 | `Array<{ label: string; value: unknown }> \| unknown[]` |
|
|
615
|
+
| `isFieldLoading(field)` | 获取指定字段的加载状态 | `boolean` |
|
|
616
|
+
| `getComponentInstance(field)` | 获取组件实例(含 `options`、`loading`、`fetchOptions`) | `ComponentPublicInstance \| null` |
|
|
617
|
+
|
|
618
|
+
**示例:联动下拉**
|
|
619
|
+
|
|
620
|
+
```vue
|
|
621
|
+
<template>
|
|
622
|
+
<ProForm ref="formRef" :schemas="schemas" @submit="handleSubmit" />
|
|
623
|
+
<el-button @click="getCityLabel">获取选中城市的名称</el-button>
|
|
624
|
+
</template>
|
|
625
|
+
|
|
626
|
+
<script setup lang="ts">
|
|
627
|
+
import { ref } from 'vue'
|
|
628
|
+
import type { ProFormSchema } from 'element-component-pro'
|
|
629
|
+
|
|
630
|
+
const formRef = ref()
|
|
631
|
+
|
|
632
|
+
const fetchProvinces = () => Promise.resolve([
|
|
633
|
+
{ label: '广东', value: 'gd' },
|
|
634
|
+
{ label: '浙江', value: 'zj' },
|
|
635
|
+
])
|
|
636
|
+
|
|
637
|
+
const fetchCities = (params) => Promise.resolve([
|
|
638
|
+
{ label: '广州', value: 'gz' },
|
|
639
|
+
{ label: '深圳', value: 'sz' },
|
|
640
|
+
])
|
|
641
|
+
|
|
642
|
+
const schemas: ProFormSchema[] = [
|
|
643
|
+
{
|
|
644
|
+
field: 'province',
|
|
645
|
+
label: '省份',
|
|
646
|
+
component: 'api-select',
|
|
647
|
+
componentProps: {
|
|
648
|
+
api: fetchProvinces,
|
|
649
|
+
onChange: () => {
|
|
650
|
+
// 省份变化时,清空城市并触发重新加载
|
|
651
|
+
formRef.value.setFieldsValue({ city: null })
|
|
652
|
+
formRef.value.updateSchema([{
|
|
653
|
+
field: 'city',
|
|
654
|
+
componentProps: { params: { provinceId: formRef.value.getFieldsValue().province } }
|
|
655
|
+
}])
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
field: 'city',
|
|
661
|
+
label: '城市',
|
|
662
|
+
component: 'api-select',
|
|
663
|
+
componentProps: {
|
|
664
|
+
api: fetchCities,
|
|
665
|
+
params: { provinceId: '' }
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
]
|
|
669
|
+
|
|
670
|
+
const getCityLabel = () => {
|
|
671
|
+
const options = formRef.value.getFieldOptions('city')
|
|
672
|
+
const rawOptions = formRef.value.getFieldOptions('city', true)
|
|
673
|
+
const currentValue = formRef.value.getFieldsValue().city
|
|
674
|
+
const label = options.find(o => o.value === currentValue)?.label
|
|
675
|
+
console.log('当前选中城市:', label)
|
|
676
|
+
console.log('城市原始数据:', rawOptions)
|
|
677
|
+
}
|
|
678
|
+
</script>
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
**示例:在 componentProps 回调中获取 Options**
|
|
682
|
+
|
|
683
|
+
```ts
|
|
684
|
+
{
|
|
685
|
+
field: 'category',
|
|
686
|
+
label: '子类目',
|
|
687
|
+
component: 'api-select',
|
|
688
|
+
componentProps: ({ formActionType }) => ({
|
|
689
|
+
api: fetchCategoryList,
|
|
690
|
+
params: { type: formActionType.getFieldsValue().type },
|
|
691
|
+
onChange: (value) => {
|
|
692
|
+
// 在回调中也能获取到当前 options 和原始数据
|
|
693
|
+
const options = formActionType.getFieldOptions('category')
|
|
694
|
+
const rawOptions = formActionType.getFieldOptions('category', true)
|
|
695
|
+
console.log('子类目 Options:', options)
|
|
696
|
+
console.log('子类目原始数据:', rawOptions)
|
|
697
|
+
}
|
|
698
|
+
}),
|
|
699
|
+
}
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
### tree-select(树选择)
|
|
703
|
+
|
|
704
|
+
树形数据选择,支持 **直接传入 treeData** 或 **api + params** 远程拉取;**treeData 优先**,仅当未传 treeData(或为空数组)时才请求 api。
|
|
705
|
+
|
|
706
|
+
- **treeData**:树形数组,直接传入时使用本地数据,不请求 api;可与 `labelField` / `valueField` / `childrenField` 配合使用。
|
|
707
|
+
- **api**:`(params?) => Promise<树数据>`,在未提供 treeData 时拉取树数据;返回值为树形数组,每项含 `label`、`value`、`children`(字段名可通过 `labelField` / `valueField` / `childrenField` 配置)。
|
|
708
|
+
- **params**:请求参数,变化时重新拉取(仅在使用 api 时生效)。
|
|
709
|
+
- **filterable**:为 true 时下拉内显示搜索框,按关键字过滤树节点(前端过滤)。
|
|
710
|
+
- **lazy**:为 true 时在展开下拉时再请求数据(仅在使用 api 时生效)。
|
|
711
|
+
|
|
712
|
+
仅用 treeData 示例:
|
|
713
|
+
|
|
714
|
+
```ts
|
|
715
|
+
{
|
|
716
|
+
field: 'deptId',
|
|
717
|
+
label: '部门',
|
|
718
|
+
component: 'tree-select',
|
|
719
|
+
componentProps: {
|
|
720
|
+
treeData: [
|
|
721
|
+
{ label: '总部', value: 'hq', children: [
|
|
722
|
+
{ label: '技术部', value: 'hq-tech' },
|
|
723
|
+
{ label: '产品部', value: 'hq-product' },
|
|
724
|
+
]},
|
|
725
|
+
{ label: '华东区', value: 'east', children: [
|
|
726
|
+
{ label: '上海分公司', value: 'east-sh' },
|
|
727
|
+
]},
|
|
728
|
+
],
|
|
729
|
+
labelField: 'label',
|
|
730
|
+
valueField: 'value',
|
|
731
|
+
childrenField: 'children',
|
|
732
|
+
filterable: true,
|
|
733
|
+
placeholder: '请选择部门',
|
|
734
|
+
clearable: true,
|
|
735
|
+
},
|
|
736
|
+
}
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
使用 api 示例:
|
|
740
|
+
|
|
741
|
+
```ts
|
|
742
|
+
{
|
|
743
|
+
field: 'deptId',
|
|
744
|
+
label: '部门',
|
|
745
|
+
component: 'tree-select',
|
|
746
|
+
componentProps: {
|
|
747
|
+
api: () => api.getDeptTree(),
|
|
748
|
+
params: { type: 1 },
|
|
749
|
+
labelField: 'name',
|
|
750
|
+
valueField: 'id',
|
|
751
|
+
childrenField: 'children',
|
|
752
|
+
filterable: true,
|
|
753
|
+
placeholder: '请选择部门',
|
|
754
|
+
clearable: true,
|
|
755
|
+
},
|
|
756
|
+
}
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
### 函数形式
|
|
760
|
+
|
|
761
|
+
传入函数可获取表单上下文,适用于动态配置或联动逻辑。参数类型:
|
|
762
|
+
|
|
763
|
+
| 参数 | 类型 | 说明 |
|
|
764
|
+
|------|------|------|
|
|
765
|
+
| schema | `ProFormSchema` | 当前表单项的 schema |
|
|
766
|
+
| values | `Record<string, unknown>` | 表单数据(与 model 相同引用) |
|
|
767
|
+
| model | `Record<string, unknown>` | 表单数据,可直接修改实现联动 |
|
|
768
|
+
| field | `string` | 当前字段名 |
|
|
769
|
+
| formActionType | `FormActionType` | 表单操作 API |
|
|
770
|
+
|
|
771
|
+
```ts
|
|
772
|
+
{
|
|
773
|
+
field: 'name',
|
|
774
|
+
component: 'input',
|
|
775
|
+
componentProps: ({ values, model, formActionType }) => ({
|
|
776
|
+
// 根据其他字段动态配置
|
|
777
|
+
disabled: values.status === 0,
|
|
778
|
+
// 或使用 formActionType 编程式操作
|
|
779
|
+
onChange: (val: string) => {
|
|
780
|
+
formActionType.setFieldsValue({ otherField: val + '_suffix' })
|
|
781
|
+
},
|
|
782
|
+
}),
|
|
783
|
+
}
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
### 事件监听
|
|
787
|
+
|
|
788
|
+
以 `on` 开头的属性会被识别为事件监听器,通过 `v-on` 绑定到组件。支持 `onChange`、`onInput`、`onBlur` 等,**不区分大小写**(`onchange` 与 `onChange` 均可)。
|
|
789
|
+
|
|
790
|
+
```ts
|
|
791
|
+
{
|
|
792
|
+
field: 'remark',
|
|
793
|
+
component: 'input',
|
|
794
|
+
componentProps: ({ formActionType }) => ({
|
|
795
|
+
onChange: (value: string) => {
|
|
796
|
+
formActionType.setFieldsValue({ phone: value })
|
|
797
|
+
},
|
|
798
|
+
onInput: (value: string) => {
|
|
799
|
+
console.log('输入中', value)
|
|
800
|
+
},
|
|
801
|
+
}),
|
|
802
|
+
}
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### 各组件常用 props
|
|
806
|
+
|
|
807
|
+
| 组件 | 常用 props | 说明 |
|
|
808
|
+
|------|------------|------|
|
|
809
|
+
| input | `maxlength`, `clearable`, `showPassword`, `prefixIcon`, `suffixIcon` | 参考 [el-input](https://element.eleme.cn/#/zh-CN/component/input) |
|
|
810
|
+
| select | `options` | `{ label, value }[]`,必填 |
|
|
811
|
+
| api-select | `api`, `params`, `lazy`, `labelField`, `valueField`, `filterable` | `api` 可接收 `params`;`params` 变化时重新拉取;`lazy: true` 为懒加载;`filterable: true` 开启下拉内关键字搜索(前端过滤已加载选项),见上文 |
|
|
812
|
+
| tree-select | `treeData`, `api`, `params`, `lazy`, `labelField`, `valueField`, `childrenField`, `filterable` | 树选择;**treeData 优先**,未传时用 api/params 拉取;filterable 搜索树节点,见上文 |
|
|
813
|
+
| input-number | `min`, `max`, `step`, `precision`, `controls` | 参考 [el-input-number](https://element.eleme.cn/#/zh-CN/component/input-number) |
|
|
814
|
+
| formatted-number | 在 **`componentProps`** 中传入:`integerDigits`、`decimalPlaces`、`rounding`、`inputLimit`,以及 `clearable`、`placeholder` 等同 el-input | 仅数字输入;失焦时按整数位数上限与小数位舍入后格式化为千分位;`integerDigits` 默认 6,`decimalPlaces` 默认 6,`rounding` 为 `floor` \| `ceil` \| `round`(默认 `round`);`inputLimit` 默认 `true`,为 `true` 时输入过程中限制整数位不超过 `integerDigits`、小数位不超过 `decimalPlaces`;表单值为**固定小数位的字符串**(如 `12.340000`,以保留配置的小数位;`number` 无法保留尾随 0),清空为 `undefined` |
|
|
815
|
+
| date-picker | `value-format`, `type`, `format` | 参考 [el-date-picker](https://element.eleme.cn/#/zh-CN/component/date-picker) |
|
|
816
|
+
| switch | `activeText`, `inactiveText`, `activeValue`, `inactiveValue` | 参考 [el-switch](https://element.eleme.cn/#/zh-CN/component/switch) |
|
|
817
|
+
| cascader | `options`, `props` | 参考 [el-cascader](https://element.eleme.cn/#/zh-CN/component/cascader) |
|
|
818
|
+
| checkbox / radio | `options` | `{ label, value }[]`,必填 |
|
|
819
|
+
|
|
820
|
+
### fieldMapToTime
|
|
821
|
+
|
|
822
|
+
将日期范围映射为两个字段:
|
|
823
|
+
|
|
824
|
+
```ts
|
|
825
|
+
useForm({
|
|
826
|
+
schemas: [
|
|
827
|
+
{ field: 'dateRange', component: 'date-range', label: '日期范围' },
|
|
828
|
+
],
|
|
829
|
+
fieldMapToTime: [
|
|
830
|
+
['dateRange', ['startTime', 'endTime']],
|
|
831
|
+
],
|
|
832
|
+
})
|
|
833
|
+
// getFieldsValue() => { startTime, endTime }
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
### formListeners
|
|
837
|
+
|
|
838
|
+
透传事件监听器到 el-form:
|
|
839
|
+
|
|
840
|
+
```vue
|
|
841
|
+
<ProForm
|
|
842
|
+
:schemas="schemas"
|
|
843
|
+
:form-listeners="{
|
|
844
|
+
validate: (valid) => console.log('validate', valid),
|
|
845
|
+
'validate-field': (prop, valid, msg) => {},
|
|
846
|
+
}"
|
|
847
|
+
@submit="handleSubmit"
|
|
848
|
+
/>
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
## FormActions 组件
|
|
852
|
+
|
|
853
|
+
提交/重置/展开按钮组已抽离为独立组件,可单独使用。提交、重置按钮默认带图标。
|
|
854
|
+
|
|
855
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
856
|
+
|------|------|--------|------|
|
|
857
|
+
| submitButtonText | `string` | `'提交'` | 提交按钮文字 |
|
|
858
|
+
| resetButtonText | `string` | `'重置'` | 重置按钮文字 |
|
|
859
|
+
| submitButtonIcon | `string` | `'el-icon-search'` | 提交按钮图标 |
|
|
860
|
+
| resetButtonIcon | `string` | `'el-icon-refresh-left'` | 重置按钮图标 |
|
|
861
|
+
| submitLoading | `boolean` | `false` | 提交中 loading 状态 |
|
|
862
|
+
|
|
863
|
+
```vue
|
|
864
|
+
<template>
|
|
865
|
+
<FormActions
|
|
866
|
+
:submit-loading="loading"
|
|
867
|
+
submit-button-text="查询"
|
|
868
|
+
reset-button-text="重置"
|
|
869
|
+
submit-button-icon="el-icon-search"
|
|
870
|
+
reset-button-icon="el-icon-refresh-left"
|
|
871
|
+
@submit="handleSubmit"
|
|
872
|
+
@reset="handleReset"
|
|
873
|
+
/>
|
|
874
|
+
</template>
|
|
875
|
+
|
|
876
|
+
<script setup lang="ts">
|
|
877
|
+
import { FormActions } from 'element-component-pro'
|
|
878
|
+
</script>
|
|
879
|
+
```
|