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

11 KiB
Raw Blame History

动态表单组件组使用文档

版本: v1.0.0 作者: 动态表单组件组 创建时间: 2025-01-24


📋 目录

  1. 组件概述
  2. 核心组件
  3. 字段组件
  4. 工具函数
  5. Composable
  6. 使用示例
  7. 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 动态字段渲染器

最核心的组件,根据字段配置动态渲染表单。

基础用法

<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命名assetNamepurchaseDate
  • 避免使用保留字:nameidvalue
  • 使用语义化命名:cpuModel 而非 field1

2. 验证规则设置

  • 必填字段始终设置 required: true
  • 文本字段设置合理的 max 限制
  • 数字字段设置 minmax 范围
  • 使用 custom 进行复杂验证

3. 字段联动设计

  • 避免循环依赖
  • 条件函数保持简单
  • 联动动作尽可能轻量

4. 性能优化

  • 使用字段缓存减少API请求
  • 大表单使用懒加载
  • 合理设置字段span优化布局

5. 错误处理

  • 提供清晰的错误提示
  • 使用自定义错误消息
  • 验证失败时高亮显示错误字段

更新日志

v1.0.0 (2025-01-24)

  • 初始版本发布
  • 支持基础字段类型
  • 实现字段验证
  • 实现字段联动
  • 实现栅格布局
  • 📝 完善文档和示例

支持

如有问题或建议,请联系开发团队。