- 修复路由守卫:未登录时直接跳转,不显示提示信息 - 修复API拦截器:401错误直接跳转,无需确认 - 移除不必要的ElMessageBox确认框 - 优化Token过期处理逻辑 - 修复文件管理API引入路径和URL前缀 - 修复调拨/回收管理API端点不匹配问题 - 修复通知管理API方法不匹配问题 - 统一系统配置API路径为单数形式 影响文件: - src/router/index.ts - src/api/request.ts - src/api/file.ts - src/api/index.ts 测试状态: - 前端构建通过 - 所有API路径已验证 - 登录流程测试通过 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
11 KiB
11 KiB
动态表单组件组使用文档
版本: v1.0.0 作者: 动态表单组件组 创建时间: 2025-01-24
📋 目录
组件概述
动态表单组件组是资产管理系统的核心组件库,用于支持不同设备类型的自定义字段渲染和验证。
主要特性
- ✅ 支持多种字段类型(text、number、date、select、multiselect、boolean、textarea、tree等)
- ✅ 动态验证规则(必填、长度、正则、自定义验证)
- ✅ 字段联动(显示/隐藏、启用/禁用、值联动)
- ✅ 栅格布局支持
- ✅ 响应式设计
- ✅ TypeScript完整类型支持
- ✅ 统一的API接口
组件清单
| 组件名称 | 文件路径 | 功能说明 |
|---|---|---|
| DynamicFieldRenderer | @/components/form/DynamicFieldRenderer.vue |
动态字段渲染器(核心组件) |
| FieldDesigner | @/components/form/FieldDesigner.vue |
字段配置设计器 |
| TextField | @/components/form/fields/TextField.vue |
单行文本输入 |
| NumberField | @/components/form/fields/NumberField.vue |
数字输入 |
| TextareaField | @/components/form/fields/TextareaField.vue |
多行文本输入 |
| DateField | @/components/form/fields/DateField.vue |
日期选择器 |
| SelectField | @/components/form/fields/SelectField.vue |
下拉选择器 |
| MultiSelectField | @/components/form/fields/MultiSelectField.vue |
多选下拉 |
| BooleanField | @/components/form/fields/BooleanField.vue |
开关/复选框 |
| TreeSelect | @/components/common/TreeSelect.vue |
树形选择器 |
核心组件
DynamicFieldRenderer 动态字段渲染器
最核心的组件,根据字段配置动态渲染表单。
基础用法
<template>
<DynamicFieldRenderer
ref="formRef"
v-model="formData"
:fields="fields"
@field-change="handleFieldChange"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import DynamicFieldRenderer from '@/components/form/DynamicFieldRenderer.vue'
import type { FieldConfig } from '@/types/form'
const formRef = ref()
const formData = ref({
assetName: '',
cpu: '',
memory: ''
})
const fields: FieldConfig[] = [
{
id: '1',
name: 'assetName',
label: '资产名称',
fieldType: 'text',
required: true,
span: 12
},
{
id: '2',
name: 'cpu',
label: 'CPU型号',
fieldType: 'text',
required: true,
span: 12
}
]
</script>
Props
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| modelValue | FormData |
- | 表单数据(v-model) |
| fields | FieldConfig[] |
[] | 字段配置列表 |
| readonly | boolean |
false | 是否只读模式 |
| labelWidth | string | number |
'120px' | 标签宽度 |
| labelPosition | 'left' | 'right' | 'top' |
'right' | 标签位置 |
| gutter | number |
20 | 栅格间隔 |
| dependencies | FieldDependency[] |
[] | 字段联动配置 |
Emits
| 事件名 | 参数 | 说明 |
|---|---|---|
| update:modelValue | (value: FormData) |
表单数据更新 |
| field-change | (event: FieldChangeEvent) |
字段值变化 |
| validation-change | (state: FormValidationState) |
验证状态变化 |
Methods
| 方法名 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| validateField | (fieldName: string) |
Promise<boolean> |
验证单个字段 |
| validateForm | - | Promise<boolean> |
验证整个表单 |
| resetForm | - | void |
重置表单 |
| clearValidation | - | void |
清除验证 |
| setFieldValue | (fieldName: string, value: any) |
void |
设置字段值 |
| getFieldValue | (fieldName: string) |
any |
获取字段值 |
| getFormData | - | FormData |
获取表单数据 |
| setFormData | (data: FormData) |
void |
设置表单数据 |
字段组件
FieldConfig 字段配置
interface FieldConfig {
id: string // 字段唯一标识
name: string // 字段名称(用于提交)
label: string // 字段标签(显示名称)
fieldType: FieldType // 字段类型
required?: boolean // 是否必填
defaultValue?: any // 默认值
placeholder?: string // 占位符
options?: Array<{ // 选项(select/multiselect)
label: string
value: any
disabled?: boolean
}>
validationRules?: { // 验证规则
min?: number
max?: number
pattern?: string
custom?: (value: any, allData: Record<string, any>) => boolean | string
customMessage?: string
}
span?: number // 栅格占列数(1-24)
visible?: boolean | ((data: Record<string, any>) => boolean) // 是否显示
disabled?: boolean | ((data: Record<string, any>) => boolean) // 是否禁用
description?: string // 字段描述
className?: string // 自定义类名
treeData?: TreeNode[] // 树形数据(tree类型)
multiple?: boolean // 是否多选(tree类型)
}
字段类型(FieldType)
| 类型 | 说明 | 组件 |
|---|---|---|
text |
单行文本 | TextField |
textarea |
多行文本 | TextareaField |
number |
数字输入 | NumberField |
date |
日期选择 | DateField |
select |
下拉选择 | SelectField |
multiselect |
多选下拉 | MultiSelectField |
boolean |
开关/复选框 | BooleanField |
tree |
树形选择 | TreeSelect |
url |
URL链接 | TextField(带验证) |
email |
邮箱 | TextField(带验证) |
phone |
手机号 | TextField(带验证) |
工具函数
fieldValidator 字段验证器
import { validateField, validateFields } from '@/utils/fieldValidator'
// 验证单个字段
const result = validateField(value, field, allFormData)
// 返回: { isValid: boolean, errors: string[] }
// 验证所有字段
const errors = validateFields(data, fields)
// 返回: Record<string, string[]>
FieldDependencyManager 字段联动管理器
import { FieldDependencyManager, DependencyConditions, DependencyActions } from '@/utils/fieldDependency'
const manager = new FieldDependencyManager()
// 添加联动配置
manager.addDependency({
sourceField: 'deviceType',
targetField: 'cpu',
type: 'show',
condition: DependencyConditions.equals('desktop')
})
// 触发联动
const results = manager.trigger('deviceType', 'desktop', formData)
Composable
useDynamicForm
动态表单状态管理。
import { useDynamicForm } from '@/composables/useDynamicForm'
const {
formData, // 表单数据
validationErrors, // 验证错误
isValid, // 是否有效
isDirty, // 是否已修改
isSubmitting, // 是否正在提交
setFieldValue, // 设置字段值
validateField, // 验证字段
validateAll, // 验证所有
resetForm, // 重置表单
getFormData, // 获取表单数据
submitForm // 提交表单
} = useDynamicForm(fields)
useFieldConfig
字段配置管理。
import { useFieldConfig } from '@/composables/useFieldConfig'
const {
loadFieldConfig, // 加载字段配置
getCachedFieldConfig, // 获取缓存配置
clearCache // 清除缓存
} = useFieldConfig()
// 加载设备类型的字段配置
const fields = await loadFieldConfig(deviceTypeId)
使用示例
示例1:基础表单
<template>
<DynamicFieldRenderer
v-model="formData"
:fields="fields"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import DynamicFieldRenderer from '@/components/form/DynamicFieldRenderer.vue'
const formData = ref({})
const fields = [
{
id: '1',
name: 'username',
label: '用户名',
fieldType: 'text',
required: true,
validationRules: {
min: 3,
max: 20
}
},
{
id: '2',
name: 'email',
label: '邮箱',
fieldType: 'email',
required: true
}
]
</script>
示例2:带字段联动
<script setup lang="ts">
const fields = [
{
id: '1',
name: 'country',
label: '国家',
fieldType: 'select',
options: [
{ label: '中国', value: 'CN' },
{ label: '美国', value: 'US' }
]
},
{
id: '2',
name: 'province',
label: '省份',
fieldType: 'select',
options: [], // 将通过联动动态加载
visible: (data) => !!data.country // 选择国家后才显示
}
]
const dependencies = [
{
sourceField: 'country',
targetField: 'province',
type: 'setValue',
condition: () => true,
action: async (target, source) => {
// 根据选择的国家加载省份列表
const provinces = await loadProvinces(source)
return provinces
}
}
]
</script>
示例3:自定义验证
<script setup lang="ts">
const fields = [
{
id: '1',
name: 'password',
label: '密码',
fieldType: 'text',
required: true,
validationRules: {
custom: (value, allData) => {
if (value.length < 8) {
return '密码长度不能少于8位'
}
if (!/[A-Z]/.test(value)) {
return '密码必须包含大写字母'
}
return true
}
}
}
]
</script>
API文档
类型定义完整参考
详见 @/types/form.ts
常见问题
Q: 如何动态加载选项?
A: 使用字段联动配置的 setValue 类型配合异步函数:
{
sourceField: 'category',
targetField: 'product',
type: 'setValue',
condition: () => true,
action: async () => {
const products = await api.getProducts()
return products
}
}
Q: 如何实现条件验证?
A: 使用 custom 验证函数:
validationRules: {
custom: (value, allData) => {
if (allData.type === 'special' && !value) {
return '特殊类型必须填写此字段'
}
return true
}
}
最佳实践
1. 字段命名规范
- 使用camelCase命名:
assetName、purchaseDate - 避免使用保留字:
name、id、value - 使用语义化命名:
cpuModel而非field1
2. 验证规则设置
- 必填字段始终设置
required: true - 文本字段设置合理的
max限制 - 数字字段设置
min和max范围 - 使用
custom进行复杂验证
3. 字段联动设计
- 避免循环依赖
- 条件函数保持简单
- 联动动作尽可能轻量
4. 性能优化
- 使用字段缓存减少API请求
- 大表单使用懒加载
- 合理设置字段span优化布局
5. 错误处理
- 提供清晰的错误提示
- 使用自定义错误消息
- 验证失败时高亮显示错误字段
更新日志
v1.0.0 (2025-01-24)
- ✨ 初始版本发布
- ✨ 支持基础字段类型
- ✨ 实现字段验证
- ✨ 实现字段联动
- ✨ 实现栅格布局
- 📝 完善文档和示例
支持
如有问题或建议,请联系开发团队。