xdc-ui-lib 1.0.3 → 1.0.4

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 CHANGED
@@ -1,11 +1,1110 @@
1
- # xdc-ui-lib
2
-
3
- Vue 3 组件库,包含常用的业务组件。
4
-
5
- ## 组件列表
6
-
7
- - **CategorySearch**: 分类搜索组件
8
- - **BaseModal**: 模态框组件
9
- - **BaseForm**: 动态表单组件
10
- - **FileUpload**: 文件上传组件
11
-
1
+ # xdc-ui-lib
2
+
3
+ Vue 3 组件库,包含常用的业务组件。
4
+
5
+ ## 组件列表
6
+
7
+ - **CategorySearch**: 分类搜索组件
8
+ - **BaseModal**: 模态框组件
9
+ - **BaseForm**: 动态表单组件
10
+ - **FileUpload**: 文件上传组件
11
+
12
+ ## CategorySearch 分类搜索组件
13
+
14
+ 一个功能强大的分类搜索组件,支持多种筛选类型和列设置功能。
15
+
16
+ ### 基本用法
17
+
18
+ ```vue
19
+ <template>
20
+ <CategorySearch
21
+ :loading="loading"
22
+ :filter-types="filterTypes"
23
+ :columns="columns"
24
+ @search="handleSearch"
25
+ />
26
+ </template>
27
+
28
+ <script setup>
29
+ import { CategorySearch } from 'xdc-ui-lib';
30
+
31
+ const filterTypes = [
32
+ {
33
+ id: 'name',
34
+ label: '名称',
35
+ type: 'input',
36
+ placeholder: '请输入名称'
37
+ },
38
+ {
39
+ id: 'status',
40
+ label: '状态',
41
+ type: 'select',
42
+ options: [
43
+ { label: '启用', value: 1 },
44
+ { label: '禁用', value: 0 }
45
+ ]
46
+ }
47
+ ];
48
+
49
+ const columns = [
50
+ { title: '名称', dataIndex: 'name' },
51
+ { title: '状态', dataIndex: 'status' }
52
+ ];
53
+ </script>
54
+ ```
55
+
56
+ ### 支持的筛选类型
57
+
58
+ - `input`: 文本输入
59
+ - `textarea`: 多行文本
60
+ - `select`: 下拉选择
61
+ - `cascader`: 级联选择
62
+ - `treeSelect`: 树形选择
63
+ - `checkbox`: 多选框
64
+ - `radio`: 单选框
65
+ - `date`: 日期选择
66
+ - `datetime`: 日期时间选择
67
+ - `dateRange`: 日期范围
68
+ - `datetimeRange`: 日期时间范围
69
+ - `time`: 时间选择
70
+ - `numberRange`: 数字范围
71
+ - `rate`: 评分
72
+ - `slider`: 滑块
73
+ - `switch`: 开关
74
+ - `slot`: 自定义插槽
75
+
76
+ ### 高级功能
77
+
78
+ #### 1. 表单模式 (type="form")
79
+
80
+ ```vue
81
+ <template>
82
+ <CategorySearch
83
+ type="form"
84
+ :filter-types="filterTypes"
85
+ :form-layout="'vertical'"
86
+ :form-span="8"
87
+ v-model:filter-value="searchParams"
88
+ @search="handleSearch"
89
+ />
90
+ </template>
91
+ ```
92
+
93
+ #### 2. 列设置功能
94
+
95
+ ```vue
96
+ <template>
97
+ <CategorySearch
98
+ :show-setting-columns="true"
99
+ :columns="columns"
100
+ :disabled-columns="['id', 'name']"
101
+ @columns-change="handleColumnsChange"
102
+ />
103
+ </template>
104
+ ```
105
+
106
+ #### 3. 自定义插槽
107
+
108
+ ```vue
109
+ <template>
110
+ <CategorySearch :filter-types="filterTypes">
111
+ <template #filter-slots="{ filter, filterTemp, confirm }">
112
+ <CustomComponent
113
+ v-if="filter.id === 'customField'"
114
+ v-model:value="filterTemp[filter.id]"
115
+ @change="confirm"
116
+ />
117
+ </template>
118
+ </CategorySearch>
119
+ </template>
120
+ ```
121
+
122
+ #### 4. 国际化支持
123
+
124
+ ```javascript
125
+ const filterTypes = [
126
+ {
127
+ id: 'status',
128
+ type: 'select',
129
+ label: $t('table.probe') + $t('table.Blank') + $t('table.Status'),
130
+ options: [...]
131
+ }
132
+ ];
133
+ ```
134
+
135
+ ### Props
136
+
137
+ | 参数 | 说明 | 类型 | 默认值 |
138
+ |------|------|------|--------|
139
+ | type | 搜索模式 | 'input' \| 'form' | 'input' |
140
+ | filterValue | 默认的筛选条件 | object | {} |
141
+ | loading | 加载状态 | boolean | - |
142
+ | filterTypes | 筛选类型配置 | array | [] |
143
+ | placeholder | 输入框占位符 | string | '点击选择搜索条件' |
144
+ | storageKey | 存储键,如果提供则使用,否则自动生成 | string | '' |
145
+ | hideRefresh | 是否隐藏刷新按钮 | boolean | false |
146
+ | showSwitch | 是否显示切换按钮 | boolean | false |
147
+ | showSave | 是否显示保存按钮 | boolean | false |
148
+ | showSettingColumns | 是否显示列设置 | boolean | true |
149
+ | columns | 表格列配置 | array | [] |
150
+ | disabledColumns | 禁用的列 | array | ['id', 'name'] |
151
+ | isDefaultSearch | 是否默认执行搜索 | boolean | true |
152
+ | formLayout | 表单布局 | 'horizontal' \| 'vertical' \| 'grid' | 'horizontal' |
153
+ | formSpan | 表单网格列数 | number | 2 |
154
+ | labelBorder | 是否显示标签边框 | boolean | false |
155
+
156
+ ### 存储键生成规则
157
+
158
+ 组件会根据以下规则生成存储键:
159
+
160
+ 1. **如果提供了 `storageKey`**:直接使用提供的值
161
+ 2. **如果没有提供 `storageKey`**:自动生成基于页面路径和配置的唯一键
162
+
163
+ #### 自动生成存储键
164
+
165
+ 当没有提供 `storageKey` 时,组件会自动生成一个基于以下信息的唯一存储键:
166
+ - 当前页面路径
167
+ - 筛选类型配置
168
+ - 表格列配置
169
+
170
+ 生成的键格式为:`category_search_auto_${hash}`
171
+
172
+ 这样可以确保每个页面和配置组合都有唯一的存储键,避免数据冲突。
173
+
174
+ ### 在 Vue Router 项目中使用
175
+
176
+ ```vue
177
+ <template>
178
+ <!-- 使用路由名称作为存储键 -->
179
+ <CategorySearch
180
+ :storage-key="`search-${$route.name}`"
181
+ :loading="loading"
182
+ :filter-types="filterTypes"
183
+ @search="handleSearch"
184
+ />
185
+ </template>
186
+ ```
187
+
188
+ ### 在非路由项目中使用
189
+
190
+ ```vue
191
+ <template>
192
+ <CategorySearch
193
+ storage-key="user-list-search"
194
+ :loading="loading"
195
+ :filter-types="filterTypes"
196
+ @search="handleSearch"
197
+ />
198
+ </template>
199
+ ```
200
+
201
+ ### 使用自动生成存储键
202
+
203
+ ```vue
204
+ <template>
205
+ <!-- 不提供 storageKey,自动生成 -->
206
+ <CategorySearch
207
+ :loading="loading"
208
+ :filter-types="filterTypes"
209
+ :columns="columns"
210
+ @search="handleSearch"
211
+ />
212
+ </template>
213
+ ```
214
+
215
+ ### Events
216
+
217
+ | 事件名 | 说明 | 回调参数 |
218
+ |--------|------|----------|
219
+ | search | 搜索事件 | (params: object) |
220
+ | switch | 切换事件 | (filters: array) |
221
+ | clear | 清空事件 | - |
222
+ | reset | 重置事件 | - |
223
+ | columnsChange | 列变化事件 | (columns: array) |
224
+ | update:columns | 列更新事件 | (columns: array) |
225
+ | update:filterValue | 筛选值更新事件 | (value: object) |
226
+
227
+ ## BaseForm 动态表单组件
228
+
229
+ 一个功能强大的动态表单组件,支持多种表单元素类型、布局方式和自定义功能。
230
+
231
+ ### 基本用法
232
+
233
+ ```vue
234
+ <template>
235
+ <BaseForm
236
+ v-model="formData"
237
+ :items="formItems"
238
+ :submit-loading="loading"
239
+ submit-text="提交"
240
+ @submit="handleSubmit"
241
+ />
242
+ </template>
243
+
244
+ <script setup>
245
+ import { BaseForm } from 'xdc-ui-lib';
246
+
247
+ const formData = reactive({
248
+ username: '',
249
+ email: '',
250
+ age: null,
251
+ gender: '',
252
+ hobbies: []
253
+ });
254
+
255
+ const formItems = [
256
+ {
257
+ name: 'username',
258
+ label: '用户名',
259
+ type: 'input',
260
+ placeholder: '请输入用户名',
261
+ required: true,
262
+ rules: [
263
+ { required: true, message: '请输入用户名' },
264
+ { min: 3, max: 20, message: '用户名长度为3-20个字符' }
265
+ ]
266
+ },
267
+ {
268
+ name: 'email',
269
+ label: '邮箱',
270
+ type: 'input',
271
+ placeholder: '请输入邮箱',
272
+ required: true,
273
+ rules: [
274
+ { required: true, message: '请输入邮箱' },
275
+ { type: 'email', message: '请输入正确的邮箱格式' }
276
+ ]
277
+ },
278
+ {
279
+ name: 'age',
280
+ label: '年龄',
281
+ type: 'number',
282
+ min: 0,
283
+ max: 120
284
+ },
285
+ {
286
+ name: 'gender',
287
+ label: '性别',
288
+ type: 'radio',
289
+ options: [
290
+ { label: '男', value: 'male' },
291
+ { label: '女', value: 'female' }
292
+ ]
293
+ },
294
+ {
295
+ name: 'hobbies',
296
+ label: '兴趣爱好',
297
+ type: 'checkbox',
298
+ options: [
299
+ { label: '读书', value: 'reading' },
300
+ { label: '运动', value: 'sports' },
301
+ { label: '音乐', value: 'music' }
302
+ ]
303
+ }
304
+ ];
305
+ </script>
306
+ ```
307
+
308
+ ### 支持的表单元素类型
309
+
310
+ - `input`: 文本输入框
311
+ - `password`: 密码输入框
312
+ - `textarea`: 多行文本框
313
+ - `number`: 数字输入框
314
+ - `select`: 下拉选择器
315
+ - `treeSelect`: 树形选择器
316
+ - `radio`: 单选框组
317
+ - `checkbox`: 复选框组
318
+ - `checkbox-single`: 单个复选框
319
+ - `switch`: 开关
320
+ - `date`: 日期选择器
321
+ - `time`: 时间选择器
322
+ - `dateRange`: 日期范围选择器
323
+ - `slider`: 滑块
324
+ - `rate`: 评分
325
+ - `custom`: 自定义组件
326
+
327
+ ### 布局方式
328
+
329
+ #### 1. 水平布局 (默认)
330
+
331
+ ```vue
332
+ <BaseForm
333
+ :items="formItems"
334
+ layout="horizontal"
335
+ :label-col="{ span: 4 }"
336
+ :wrapper-col="{ span: 20 }"
337
+ />
338
+ ```
339
+
340
+ #### 2. 垂直布局
341
+
342
+ ```vue
343
+ <BaseForm
344
+ :items="formItems"
345
+ layout="vertical"
346
+ />
347
+ ```
348
+
349
+ #### 3. 网格布局
350
+
351
+ ```vue
352
+ <BaseForm
353
+ :items="formItems"
354
+ layout="grid"
355
+ :columns="3"
356
+ />
357
+ ```
358
+
359
+ ### 自定义插槽
360
+
361
+ #### 1. 自定义表单项
362
+
363
+ ```vue
364
+ <BaseForm :items="formItems">
365
+ <template #field-customField="{ item, modelValue, updateValue }">
366
+ <div class="custom-field">
367
+ <a-input
368
+ :value="modelValue"
369
+ placeholder="自定义字段"
370
+ @input="(e) => updateValue(e.target.value)"
371
+ />
372
+ </div>
373
+ </template>
374
+ </BaseForm>
375
+ ```
376
+
377
+ #### 2. 自定义操作按钮
378
+
379
+ ```vue
380
+ <BaseForm :items="formItems" :show-actions="true">
381
+ <template #actions="{ submit, reset, validateForm, formData, loading }">
382
+ <a-space>
383
+ <a-button type="primary" :loading="loading" @click="submit">
384
+ 确认提交
385
+ </a-button>
386
+ <a-button @click="reset">重置</a-button>
387
+ <a-button type="dashed" @click="handlePreview">
388
+ 预览数据
389
+ </a-button>
390
+ </a-space>
391
+ </template>
392
+ </BaseForm>
393
+ ```
394
+
395
+ #### 3. 自定义表单项前缀/后缀
396
+
397
+ ```vue
398
+ <BaseForm :items="formItems">
399
+ <!-- 只在 input 类型的表单项中可用 -->
400
+ <template #username-prefix>
401
+ <UserOutlined />
402
+ </template>
403
+ <template #username-suffix>
404
+ <InfoCircleOutlined />
405
+ </template>
406
+ <template #username-after="{ item, value }">
407
+ <small>用户名将用于登录</small>
408
+ </template>
409
+ </BaseForm>
410
+ ```
411
+
412
+ #### 4. 自定义整个表单项
413
+
414
+ ```vue
415
+ <BaseForm :items="formItems">
416
+ <template #form-item-customField="{ item, modelValue, updateValue }">
417
+ <a-form-item :label="item.label">
418
+ <div class="custom-form-item">
419
+ <a-input :value="modelValue" placeholder="自定义表单项" @input="(e) => updateValue(e.target.value)" />
420
+ <small>这是完全自定义的表单项</small>
421
+ </div>
422
+ </a-form-item>
423
+ </template>
424
+ </BaseForm>
425
+ ```
426
+
427
+ #### 5. 自定义表单项插槽
428
+
429
+ ```vue
430
+ <BaseForm :items="formItems">
431
+ <template #custom-items="{ formData, updateField, formRef }">
432
+ <a-form-item label="自定义表单项">
433
+ <a-input v-model:value="formData.customField" placeholder="自定义字段" />
434
+ </a-form-item>
435
+ </template>
436
+ </BaseForm>
437
+ ```
438
+
439
+ ### 复杂表单示例
440
+
441
+ ```vue
442
+ <template>
443
+ <BaseForm
444
+ ref="formRef"
445
+ v-model="formData"
446
+ :items="formItems"
447
+ :initial-values="initialValues"
448
+ :submit-loading="loading"
449
+ submit-text="创建用户"
450
+ @submit="handleSubmit"
451
+ @field-change="handleFieldChange"
452
+ >
453
+ <!-- 头像上传自定义字段 -->
454
+ <template #field-avatar="{ modelValue, updateValue }">
455
+ <div class="avatar-upload">
456
+ <a-upload
457
+ name="avatar"
458
+ list-type="picture-card"
459
+ :show-upload-list="false"
460
+ :before-upload="beforeUpload"
461
+ @change="(info) => handleAvatarChange(info, updateValue)"
462
+ >
463
+ <img v-if="modelValue" :src="modelValue" alt="avatar" />
464
+ <div v-else>
465
+ <PlusOutlined />
466
+ <div>上传头像</div>
467
+ </div>
468
+ </a-upload>
469
+ </div>
470
+ </template>
471
+
472
+ <!-- 技能标签自定义字段 -->
473
+ <template #field-skills="{ modelValue, updateValue }">
474
+ <a-select
475
+ :value="modelValue"
476
+ mode="tags"
477
+ placeholder="输入技能并按回车添加"
478
+ @change="updateValue"
479
+ />
480
+ </template>
481
+ </BaseForm>
482
+ </template>
483
+ ```
484
+
485
+ ### Props
486
+
487
+ | 参数 | 说明 | 类型 | 默认值 |
488
+ |------|------|------|--------|
489
+ | modelValue | 表单数据模型 | object | {} |
490
+ | items | 表单项配置数组 | array | [] |
491
+ | layout | 表单布局 | 'horizontal' \| 'vertical' \| 'grid' | 'horizontal' |
492
+ | columns | 网格布局列数 | number | 2 |
493
+ | labelCol | 标签列配置 | object | { span: 4 } |
494
+ | wrapperCol | 控件列配置 | object | { span: 20 } |
495
+ | colon | 是否显示冒号 | boolean | true |
496
+ | labelAlign | 标签对齐方式 | 'left' \| 'right' | 'right' |
497
+ | scrollToFirstError | 是否滚动到第一个错误字段 | boolean | true |
498
+ | showActions | 是否显示操作按钮 | boolean | false |
499
+ | hideDefaultActions | 是否隐藏默认操作按钮 | boolean | false |
500
+ | showReset | 是否显示重置按钮 | boolean | true |
501
+ | submitText | 提交按钮文本 | string | '提交' |
502
+ | resetText | 重置按钮文本 | string | '重置' |
503
+ | submitLoading | 提交时是否显示加载状态 | boolean | false |
504
+ | initialValues | 初始值 | object | {} |
505
+
506
+ ### Events
507
+
508
+ | 事件名 | 说明 | 回调参数 |
509
+ |--------|------|----------|
510
+ | update:modelValue | 模型值更新事件 | (value: object) |
511
+ | submit | 提交事件 | (values: object) |
512
+ | reset | 重置事件 | (values: object) |
513
+ | finish | 表单提交成功事件 | (values: object) |
514
+ | finish-failed | 表单提交失败事件 | (errorInfo: any) |
515
+ | values-change | 表单值变化事件 | (changedValues: object, values: object) |
516
+ | field-change | 字段值变化事件 | (name: string, value: any, item: object) |
517
+ | field-blur | 字段失焦事件 | (name: string, value: any, item: object) |
518
+ | field-search | 字段搜索事件 | (name: string, value: string, item: object) |
519
+ | field-press-enter | 字段回车事件 | (name: string, value: any, item: object) |
520
+
521
+ ### 组件方法
522
+
523
+ | 方法名 | 说明 | 参数 |
524
+ |--------|------|------|
525
+ | validateForm | 验证表单 | (nameList?: string[]) |
526
+ | validateFields | 验证指定字段 | (nameList?: string[]) |
527
+ | clearValidate | 清除验证状态 | (nameList?: string[]) |
528
+ | setFieldsValue | 设置字段值 | (values: object) |
529
+ | getFieldsValue | 获取字段值 | (nameList?: string[]) |
530
+ | handleSubmit | 手动提交表单 | - |
531
+ | handleReset | 重置表单 | - |
532
+ | updateFieldValue | 更新字段值 | (name: string, value: any) |
533
+ | updateFieldOptions | 更新字段选项 | (fieldName: string, options: array) |
534
+ | updateFieldTreeData | 更新树形数据 | (fieldName: string, treeData: array) |
535
+ | updateFieldConfig | 更新字段配置 | (fieldName: string, config: object) |
536
+ | setFieldsValueWithTrigger | 批量设置字段值(支持联动) | (values: object, triggerChange?: boolean) |
537
+ | currentFormItems | 当前表单项配置(响应式) | - |
538
+
539
+ ### 表单项配置详解
540
+
541
+ #### 基础配置
542
+
543
+ ```javascript
544
+ {
545
+ name: 'fieldName', // 字段名(必填)
546
+ label: '字段标签', // 标签文本
547
+ type: 'input', // 表单元素类型
548
+ placeholder: '请输入', // 占位符
549
+ disabled: false, // 是否禁用
550
+ required: false, // 是否必填
551
+ hidden: false, // 是否隐藏
552
+ rules: [], // 验证规则
553
+ help: '帮助信息', // 帮助文本
554
+ extra: '额外信息' // 额外信息
555
+ }
556
+ ```
557
+
558
+ #### 输入框配置
559
+
560
+ ```javascript
561
+ {
562
+ name: 'username',
563
+ type: 'input',
564
+ maxLength: 20, // 最大字符长度
565
+ showCount: true, // 显示字符计数
566
+ prefix: '用户', // 前缀
567
+ suffix: '@example.com', // 后缀
568
+ addonBefore: 'http://', // 前置标签
569
+ addonAfter: '.com' // 后置标签
570
+ }
571
+ ```
572
+
573
+ #### 选择器配置
574
+
575
+ ```javascript
576
+ {
577
+ name: 'category',
578
+ type: 'select',
579
+ options: [
580
+ { label: '选项1', value: 'value1' },
581
+ { label: '选项2', value: 'value2' }
582
+ ],
583
+ showSearch: true, // 显示搜索
584
+ mode: 'multiple', // 多选模式
585
+ maxTagCount: 3, // 最多显示标签数
586
+ loading: false // 加载状态
587
+ }
588
+ ```
589
+
590
+ #### 日期时间配置
591
+
592
+ ```javascript
593
+ {
594
+ name: 'birthday',
595
+ type: 'date',
596
+ format: 'YYYY-MM-DD', // 显示格式
597
+ valueFormat: 'YYYY-MM-DD', // 值格式
598
+ picker: 'date', // 选择器类型
599
+ showTime: false, // 是否显示时间
600
+ disabledDate: (date) => date && date > dayjs().endOf('day') // 禁用日期
601
+ }
602
+ ```
603
+
604
+ #### 验证规则配置
605
+
606
+ ```javascript
607
+ {
608
+ name: 'email',
609
+ type: 'input',
610
+ rules: [
611
+ { required: true, message: '请输入邮箱' },
612
+ { type: 'email', message: '请输入正确的邮箱格式' },
613
+ { min: 5, max: 50, message: '邮箱长度为5-50个字符' },
614
+ { pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: '邮箱格式不正确' }
615
+ ]
616
+ }
617
+ ```
618
+
619
+ #### 树形选择器配置
620
+
621
+ ```javascript
622
+ {
623
+ name: 'department',
624
+ type: 'treeSelect',
625
+ treeData: [
626
+ {
627
+ title: '技术部',
628
+ value: 'tech',
629
+ children: [
630
+ { title: '前端组', value: 'frontend' },
631
+ { title: '后端组', value: 'backend' }
632
+ ]
633
+ }
634
+ ],
635
+ showSearch: true,
636
+ multiple: false,
637
+ treeCheckable: false,
638
+ treeDefaultExpandAll: true
639
+ }
640
+ ```
641
+
642
+ #### 单选框配置
643
+
644
+ ```javascript
645
+ {
646
+ name: 'gender',
647
+ type: 'radio',
648
+ optionType: 'button', // 'default' | 'button'
649
+ buttonStyle: 'outline', // 'outline' | 'solid'
650
+ size: 'middle', // 'large' | 'middle' | 'small'
651
+ options: [
652
+ { label: '男', value: 'male' },
653
+ { label: '女', value: 'female' }
654
+ ]
655
+ }
656
+ ```
657
+
658
+ #### 开关配置
659
+
660
+ ```javascript
661
+ {
662
+ name: 'enabled',
663
+ type: 'switch',
664
+ checkedChildren: '开启',
665
+ unCheckedChildren: '关闭',
666
+ checkedValue: true,
667
+ unCheckedValue: false,
668
+ size: 'default' // 'default' | 'small'
669
+ }
670
+ ```
671
+
672
+ #### 滑块配置
673
+
674
+ ```javascript
675
+ {
676
+ name: 'quality',
677
+ type: 'slider',
678
+ min: 0,
679
+ max: 100,
680
+ step: 1,
681
+ range: false, // 是否为范围选择
682
+ marks: {
683
+ 0: '低',
684
+ 50: '中',
685
+ 100: '高'
686
+ },
687
+ dots: false,
688
+ included: true,
689
+ tooltip: { formatter: (value) => `${value}%` }
690
+ }
691
+ ```
692
+
693
+ #### 评分配置
694
+
695
+ ```javascript
696
+ {
697
+ name: 'rating',
698
+ type: 'rate',
699
+ count: 5,
700
+ allowHalf: true,
701
+ allowClear: true,
702
+ character: '★',
703
+ tooltips: ['很差', '差', '一般', '好', '很好']
704
+ }
705
+ ```
706
+
707
+ #### 自定义组件配置
708
+
709
+ ```javascript
710
+ {
711
+ name: 'customField',
712
+ type: 'custom',
713
+ component: CustomComponent,
714
+ props: {
715
+ // 传递给自定义组件的属性
716
+ customProp: 'value'
717
+ }
718
+ }
719
+ ```
720
+
721
+ ### 动态更新功能
722
+
723
+ #### 1. 动态更新字段选项
724
+
725
+ ```javascript
726
+ const formRef = ref();
727
+
728
+ // 更新选择器选项
729
+ formRef.value?.updateFieldOptions('category', [
730
+ { label: '新选项1', value: 'new1' },
731
+ { label: '新选项2', value: 'new2' }
732
+ ]);
733
+ ```
734
+
735
+ #### 2. 动态更新树形数据
736
+
737
+ ```javascript
738
+ // 更新树形选择器数据
739
+ formRef.value?.updateFieldTreeData('department', [
740
+ {
741
+ title: '技术部',
742
+ value: 'tech',
743
+ children: [
744
+ { title: '前端组', value: 'frontend' },
745
+ { title: '后端组', value: 'backend' }
746
+ ]
747
+ }
748
+ ]);
749
+ ```
750
+
751
+ #### 3. 动态更新字段配置
752
+
753
+ ```javascript
754
+ // 更新字段的整个配置
755
+ formRef.value?.updateFieldConfig('username', {
756
+ disabled: true,
757
+ placeholder: '用户名已被锁定'
758
+ });
759
+ ```
760
+
761
+ #### 4. 批量设置字段值
762
+
763
+ ```javascript
764
+ // 批量设置字段值,支持联动
765
+ formRef.value?.setFieldsValueWithTrigger({
766
+ department: 'tech',
767
+ position: 'developer',
768
+ skills: ['javascript', 'vue']
769
+ }, true); // 第二个参数表示是否触发 change 事件
770
+ ```
771
+
772
+ #### 5. 动态隐藏/显示表单项
773
+
774
+ ```javascript
775
+ // 在 handleFieldChange 事件中动态隐藏/显示表单项
776
+ const handleFieldChange = (name, value, item) => {
777
+ if (name === 'userType') {
778
+ // 根据用户类型隐藏/显示相关字段
779
+ if (value === 'individual') {
780
+ // 隐藏公司相关字段
781
+ formRef.value?.updateFieldConfig('companyName', { hidden: true });
782
+ formRef.value?.updateFieldConfig('companyAddress', { hidden: true });
783
+ // 显示个人相关字段
784
+ formRef.value?.updateFieldConfig('idCard', { hidden: false });
785
+ } else if (value === 'company') {
786
+ // 显示公司相关字段
787
+ formRef.value?.updateFieldConfig('companyName', { hidden: false });
788
+ formRef.value?.updateFieldConfig('companyAddress', { hidden: false });
789
+ // 隐藏个人相关字段
790
+ formRef.value?.updateFieldConfig('idCard', { hidden: true });
791
+ }
792
+ }
793
+ };
794
+ ```
795
+
796
+ #### 6. 条件显示表单项
797
+
798
+ ```javascript
799
+ // 根据多个字段值组合来控制表单项显示
800
+ const handleFieldChange = (name, value, item) => {
801
+ if (name === 'country' || name === 'region') {
802
+ const country = formData.country;
803
+ const region = formData.region;
804
+
805
+ // 只有选择特定国家和地区时才显示某些字段
806
+ if (country === 'china' && region === 'beijing') {
807
+ formRef.value?.updateFieldConfig('specialField', { hidden: false });
808
+ } else {
809
+ formRef.value?.updateFieldConfig('specialField', { hidden: true });
810
+ }
811
+ }
812
+ };
813
+ ```
814
+
815
+ #### 7. 动态禁用/启用表单项
816
+
817
+ ```javascript
818
+ // 动态禁用/启用表单项
819
+ const handleFieldChange = (name, value, item) => {
820
+ if (name === 'agreeTerms') {
821
+ // 根据是否同意条款来启用/禁用提交按钮
822
+ formRef.value?.updateFieldConfig('submitButton', {
823
+ disabled: !value
824
+ });
825
+ }
826
+ };
827
+ ```
828
+
829
+ ### 表单验证功能
830
+
831
+ #### 1. 验证整个表单
832
+
833
+ ```javascript
834
+ try {
835
+ await formRef.value?.validateForm();
836
+ console.log('表单验证通过');
837
+ } catch (error) {
838
+ console.log('表单验证失败:', error);
839
+ }
840
+ ```
841
+
842
+ #### 2. 验证指定字段
843
+
844
+ ```javascript
845
+ try {
846
+ await formRef.value?.validateFields(['username', 'email']);
847
+ console.log('指定字段验证通过');
848
+ } catch (error) {
849
+ console.log('指定字段验证失败:', error);
850
+ }
851
+ ```
852
+
853
+ #### 3. 清除验证状态
854
+
855
+ ```javascript
856
+ // 清除所有字段的验证状态
857
+ formRef.value?.clearValidate();
858
+
859
+ // 清除指定字段的验证状态
860
+ formRef.value?.clearValidate(['username', 'email']);
861
+ ```
862
+
863
+ ### 表单数据操作
864
+
865
+ #### 1. 设置字段值
866
+
867
+ ```javascript
868
+ // 设置单个或多个字段值
869
+ formRef.value?.setFieldsValue({
870
+ username: 'admin',
871
+ email: 'admin@example.com'
872
+ });
873
+ ```
874
+
875
+ #### 2. 获取字段值
876
+
877
+ ```javascript
878
+ // 获取所有字段值
879
+ const allValues = formRef.value?.getFieldsValue();
880
+
881
+ // 获取指定字段值
882
+ const specificValues = formRef.value?.getFieldsValue(['username', 'email']);
883
+ ```
884
+
885
+ ### 响应式布局
886
+
887
+ #### 1. 网格布局响应式
888
+
889
+ ```vue
890
+ <BaseForm
891
+ :items="formItems"
892
+ layout="grid"
893
+ :columns="4"
894
+ :style="{
895
+ '--form-columns-xl': 4,
896
+ '--form-columns-lg': 3,
897
+ '--form-columns-md': 2,
898
+ '--form-columns-sm': 1,
899
+ '--form-columns-xs': 1
900
+ }"
901
+ />
902
+ ```
903
+
904
+ #### 2. 自定义响应式断点
905
+
906
+ ```css
907
+ /* 自定义响应式断点 */
908
+ .base-form.layout-grid {
909
+ @media (max-width: 1600px) {
910
+ --form-columns-xl: 4;
911
+ }
912
+ @media (max-width: 1200px) {
913
+ --form-columns-lg: 3;
914
+ }
915
+ @media (max-width: 992px) {
916
+ --form-columns-md: 2;
917
+ }
918
+ @media (max-width: 768px) {
919
+ --form-columns-sm: 1;
920
+ }
921
+ @media (max-width: 576px) {
922
+ --form-columns-xs: 1;
923
+ }
924
+ }
925
+ ```
926
+
927
+ ## BaseModal 模态框组件
928
+
929
+ 一个增强的模态框组件,支持模态框管理和全局控制。
930
+
931
+ ### 基本用法
932
+
933
+ ```vue
934
+ <template>
935
+ <BaseModal
936
+ v-model="visible"
937
+ title="标题"
938
+ :width="600"
939
+ @ok="handleOk"
940
+ @cancel="handleCancel"
941
+ >
942
+ <p>模态框内容</p>
943
+ </BaseModal>
944
+ </template>
945
+
946
+ <script setup>
947
+ import { BaseModal } from 'xdc-ui-lib';
948
+
949
+ const visible = ref(false);
950
+
951
+ const handleOk = () => {
952
+ console.log('确认');
953
+ visible.value = false;
954
+ };
955
+
956
+ const handleCancel = () => {
957
+ console.log('取消');
958
+ visible.value = false;
959
+ };
960
+ </script>
961
+ ```
962
+
963
+ ### 使用模态框管理
964
+
965
+ ```vue
966
+ <template>
967
+ <BaseModal
968
+ v-model="visible"
969
+ modal-id="user-modal"
970
+ title="用户信息"
971
+ >
972
+ <p>用户信息内容</p>
973
+ </BaseModal>
974
+ </template>
975
+
976
+ <script setup>
977
+ import { BaseModal, useModalManager } from 'xdc-ui-lib';
978
+
979
+ const { closeAllModals } = useModalManager();
980
+
981
+ // 关闭所有模态框
982
+ const closeAll = () => {
983
+ closeAllModals();
984
+ };
985
+ </script>
986
+ ```
987
+
988
+ ### Props
989
+
990
+ | 参数 | 说明 | 类型 | 默认值 |
991
+ |------|------|------|--------|
992
+ | modelValue | 是否显示模态框 | boolean | false |
993
+ | open | 是否显示模态框(与 modelValue 相同) | boolean | false |
994
+ | modalId | 模态框唯一标识,用于模态框管理 | string | - |
995
+
996
+ ### Events
997
+
998
+ | 事件名 | 说明 | 回调参数 |
999
+ |--------|------|----------|
1000
+ | update:modelValue | 模态框显示状态更新 | (value: boolean) |
1001
+ | update:open | 模态框显示状态更新 | (value: boolean) |
1002
+ | ok | 确认按钮点击事件 | (e: Event) |
1003
+ | cancel | 取消按钮点击事件 | (e: Event) |
1004
+ | after-close | 模态框关闭后事件 | - |
1005
+
1006
+ ### 插槽
1007
+
1008
+ | 插槽名 | 说明 |
1009
+ |--------|------|
1010
+ | default | 模态框内容 |
1011
+ | title | 标题内容 |
1012
+ | footer | 底部内容 |
1013
+ | closeIcon | 关闭图标 |
1014
+
1015
+ ### 模态框管理 Hook
1016
+
1017
+ #### useModalManager
1018
+
1019
+ 提供模态框管理功能。
1020
+
1021
+ ```typescript
1022
+ import { useModalManager } from 'xdc-ui-lib';
1023
+
1024
+ const { registerModal, unregisterModal, closeAllModals } = useModalManager();
1025
+ ```
1026
+
1027
+ **方法:**
1028
+
1029
+ - `registerModal(id: string, ref: ModalRef)`: 注册模态框
1030
+ - `unregisterModal(id: string)`: 注销模态框
1031
+ - `closeAllModals()`: 关闭所有模态框
1032
+
1033
+ **全局事件:**
1034
+
1035
+ - `close-all-modals`: 关闭所有模态框的全局事件
1036
+
1037
+ ```javascript
1038
+ // 触发全局关闭事件
1039
+ window.dispatchEvent(new Event('close-all-modals'));
1040
+ ```
1041
+
1042
+ ## FileUpload 文件上传组件
1043
+
1044
+ 基于 [ant-design-vue](https://www.antdv.com/) 的文件上传组件,支持多选、大小限制、数量限制、删除等功能。
1045
+
1046
+ ## 安装
1047
+
1048
+ ```bash
1049
+ npm install xdc-ui-lib ant-design-vue
1050
+ ```
1051
+
1052
+ ## 使用
1053
+
1054
+ ```vue
1055
+ <template>
1056
+ <FileUpload
1057
+ :limit="3"
1058
+ :fileSizeLimit="2 * 1024 * 1024"
1059
+ btnTxt="上传文件"
1060
+ @select="onSelect"
1061
+ @exceed="onExceed"
1062
+ />
1063
+ </template>
1064
+
1065
+ <script setup>
1066
+ import { FileUpload } from 'xdc-ui-lib';
1067
+
1068
+ function onSelect(files) {
1069
+ console.log('已选文件:', files);
1070
+ }
1071
+ function onExceed(file) {
1072
+ alert('文件超出大小限制: ' + file.name);
1073
+ }
1074
+ </script>
1075
+ ```
1076
+
1077
+ ## Props
1078
+
1079
+ | 属性 | 说明 | 类型 | 默认值 |
1080
+ | -------------- | ------------------ | --------- | ----------- |
1081
+ | accept | 接受的文件类型 | string | '' |
1082
+ | btnTxt | 按钮文字 | string | '上传' |
1083
+ | btnType | 按钮类型 | string | 'button' |
1084
+ | btnProps | 按钮属性 | object | {} |
1085
+ | limit | 最大文件数 | number | 1 |
1086
+ | multiple | 是否多选 | boolean | 自动由 limit 控制 |
1087
+ | disabled | 是否禁用 | boolean | false |
1088
+ | icon | 自定义图标 | 组件/函数/null | undefined |
1089
+ | fileSizeLimit | 单文件大小限制(字节)| number | 5242880 |
1090
+
1091
+ ## 事件
1092
+
1093
+ | 事件名 | 说明 | 回调参数 |
1094
+ | -------- | ------------------ | --------------- |
1095
+ | select | 文件选择后触发 | files/file |
1096
+ | exceed | 文件超出大小限制时 | file |
1097
+
1098
+
1099
+ ## 开发
1100
+
1101
+ ```bash
1102
+ # 安装依赖
1103
+ npm install
1104
+
1105
+ # 启动开发服务器
1106
+ npm run dev
1107
+
1108
+ # 构建
1109
+ npm run build
1110
+ ```