Files
zcglxt/DYNAMIC_FORM_COMPONENTS_README.md
Claude e48975f9d5 fix: 修复前端登录体验和API调用问题
- 修复路由守卫:未登录时直接跳转,不显示提示信息
- 修复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>
2026-01-25 00:26:33 +08:00

476 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 动态表单组件组使用文档
> **版本**: v1.0.0
> **作者**: 动态表单组件组
> **创建时间**: 2025-01-24
---
## 📋 目录
1. [组件概述](#组件概述)
2. [核心组件](#核心组件)
3. [字段组件](#字段组件)
4. [工具函数](#工具函数)
5. [Composable](#composable)
6. [使用示例](#使用示例)
7. [API文档](#api文档)
8. [最佳实践](#最佳实践)
---
## 组件概述
动态表单组件组是资产管理系统的核心组件库,用于支持不同设备类型的自定义字段渲染和验证。
### 主要特性
- ✅ 支持多种字段类型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 动态字段渲染器
最核心的组件,根据字段配置动态渲染表单。
#### 基础用法
```vue
<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 字段配置
```typescript
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 字段验证器
```typescript
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 字段联动管理器
```typescript
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
动态表单状态管理。
```typescript
import { useDynamicForm } from '@/composables/useDynamicForm'
const {
formData, // 表单数据
validationErrors, // 验证错误
isValid, // 是否有效
isDirty, // 是否已修改
isSubmitting, // 是否正在提交
setFieldValue, // 设置字段值
validateField, // 验证字段
validateAll, // 验证所有
resetForm, // 重置表单
getFormData, // 获取表单数据
submitForm // 提交表单
} = useDynamicForm(fields)
```
### useFieldConfig
字段配置管理。
```typescript
import { useFieldConfig } from '@/composables/useFieldConfig'
const {
loadFieldConfig, // 加载字段配置
getCachedFieldConfig, // 获取缓存配置
clearCache // 清除缓存
} = useFieldConfig()
// 加载设备类型的字段配置
const fields = await loadFieldConfig(deviceTypeId)
```
---
## 使用示例
### 示例1基础表单
```vue
<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带字段联动
```vue
<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自定义验证
```vue
<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` 类型配合异步函数:
```typescript
{
sourceField: 'category',
targetField: 'product',
type: 'setValue',
condition: () => true,
action: async () => {
const products = await api.getProducts()
return products
}
}
```
**Q: 如何实现条件验证?**
A: 使用 `custom` 验证函数:
```typescript
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)
- ✨ 初始版本发布
- ✨ 支持基础字段类型
- ✨ 实现字段验证
- ✨ 实现字段联动
- ✨ 实现栅格布局
- 📝 完善文档和示例
---
## 支持
如有问题或建议,请联系开发团队。