Files
workspace/code/fms/.codebuddy/plans/form-component_85d80607.md
2026-08-16 22:01:32 +08:00

8.3 KiB
Raw Permalink Blame History

name, overview, design, todos
name overview design todos
form-component 为 fms-vue 组件库新增一个精简的 Form 表单组件(Form + FormItem),支持 horizontal/vertical 两种布局、基础校验规则(required/pattern/min/max/len/type/自定义 validator)、提交与重置事件,并将校验错误态自动传递给内部 Input/Select/DatePicker 等控件。
architecture styleKeywords fontSystem colorSystem
framework
vue
极简
企业级
清晰层级
token驱动
fontFamily heading subheading body
PingFang SC
size weight
18px 500
size weight
12px 500
size weight
14px 400
primary background text functional
#0f172b
#ffffff
#f5f6f8
#ffffff
#1f2329
#86909c
#ef4444
#f59e0b
#16a34a
id content status
form-core 新增 form 目录:validate.js 校验工具、tokens.css 新增 form 专属 token completed
id content status dependencies
form-container 实现 form.vue 容器:provide 上下文、字段注册、submit/submitFailed/reset 事件,参考 [skill:antdv-next] Form API completed
form-core
id content status dependencies
form-item 实现 form-item.vue 与 index.scss:label 布局、校验时机、错误态 provide,参考 [skill:antdv-next] FormItem 交互 completed
form-container
id content status dependencies
control-inject 为 Input/Select/DatePicker/RangePicker/TimeSelect 注入错误态,Button 新增 htmlType prop completed
form-item
id content status dependencies
demo-register 新增 demo/form.vue 演示页并注册到 App.vue,用 [skill:ui-ux-pro-max] 把关视觉 completed
form-container
form-item
control-inject

产品概述

一个轻量的 Form 表单组件,遵循项目开发规范,参考 antdv-next 组件库的 API 与交互设计,但刻意精简功能:仅覆盖日常表单填写、校验与提交的核心场景。

核心功能

  • 两种布局:horizontal(label 在左)与 vertical(label 在上)
  • FormItem 表单项:label、必填红星标记、辅助说明(extra)、固定提示(help)
  • 校验规则:required、pattern、min/max/len、type(email/number/integer/url)、自定义 validator(支持同步/异步)
  • 提交/重置由原生 submit/reset 事件驱动,无需 ref 实例方法
  • 校验失败自动给内部 Input/Select/DatePicker 等控件注入红色错误态(边框 + aria-invalid)
  • 支持全局 disabled、label 对齐、label 宽度、必填标记开关、label 冒号等配置
  • 提交成功 / 失败事件(submit / submitFailed),供业务层回调

技术栈

  • Vue 3 Composition API(<script setup>)+ SCSS + Lucide 图标
  • 复用现有 --fms-* CSS token;校验自研轻量实现,不引入 async-validator 新依赖

实现方案

  • 上下文传递:Form 通过 provide('fms-form') 下发配置与注册/校验机制,FormItem inject 消费并注册字段;FormItem 通过 provide('fms-form-item') 下发计算后的校验状态,Input/Select/DatePicker 等控件 inject 消费(可选注入,独立使用时行为不变,保持向后兼容)
  • 校验机制:validate.js 纯函数按规则数组逐条执行,返回 Promise<string[]>;Form 提交时遍历注册字段并行校验,全部通过 emit submit,否则 emit submitFailed 并携带 errorFields
  • 校验时机:submit 全量校验;validateTrigger 为 change 时 watch model[name] 明确依赖触发,为 blur 时通过 focusout 判断焦点离开控件区域触发
  • 性能:watch 只限定单字段依赖,不做深监听;错误状态存本地 ref,仅失败项重渲染;过渡只用颜色/透明度低成本属性并支持 prefers-reduced-motion

系统架构

flowchart TD
    Form["Form form.vue<br/>props: model/rules/layout/...<br/>provide('fms-form')"] -->|注册/校验| Item["FormItem form-item.vue<br/>props: name/label/rules/...<br/>provide('fms-form-item')"]
    Item -->|inject 可选| Input["Input / Select /<br/>DatePicker / RangePicker"]
    Form -->|原生 form submit| Validate["validate.js<br/>轻量校验纯函数"]
    Validate -->|错误数组| Item
    Item -->|is-error 样式| Input

目录结构

fms-vue/src/
├── components/ui/
│   ├── form/
│   │   ├── form.vue          # [NEW] Form 容器:配置下发、字段注册、submit/reset 事件
│   │   ├── form-item.vue     # [NEW] 表单项:label 布局、校验时机、错误态 provide
│   │   ├── validate.js       # [NEW] 校验纯函数:规则执行、消息生成,返回 Promise<string[]>
│   │   └── index.scss        # [NEW] 布局/必填星/错误提示样式(复用 token)
│   ├── input/input.vue       # [MODIFY] 可选 inject fms-form-item,合并错误态
│   ├── select/select.vue     # [MODIFY] 同上;index.scss 增加 is-error/is-warning 触发器边框
│   ├── date/date-picker.vue  # [MODIFY] 同上
│   ├── date/range-picker.vue # [MODIFY] 同上
│   ├── date/time-select.vue  # [MODIFY] 同上(时间选择在表单中展示错误态)
│   ├── date/index.scss       # [MODIFY] 增加 .is-error .fms-date-trigger 等红色边框
│   ├── button/button.vue     # [MODIFY] 新增 htmlType prop(button|submit|reset)
│   └── demo/form.vue         # [NEW] 演示页:基础/纵向/自定义校验/错误态联动
├── theme/tokens.css          # [MODIFY] 新增 form 专属 token
└── App.vue                   # [MODIFY] 「数据录入」分类注册 Form 表单 demo

关键代码结构

// validate.js —— 校验纯函数签名
export function validateRules(name, label, value, rules) // Promise<string[]>
// 规则对象支持:{ required, pattern, min, max, len, type, message, validator }
// validator: (value) => boolean | string | Promise<boolean | string>

// fms-form 上下文(form.vue provide)
{ model, rules, layout, labelAlign, labelWidth, requiredMark, disabled,
  validateTrigger, colon, registerField(name, validateFn), unregisterField(name), validateAll() }

// fms-form-item 上下文(form-item.vue provide,供控件可选消费)
{ status, errorMessage }

实现注意事项

  • 遵循 开发规范.md:props 全带类型/默认值、枚举带 validator、代码分块注释、样式只用 token、不主动构建测试
  • Button 现有 type 是视觉变体(default/secondary/...),新 prop 命名 htmlType 映射原生 type,避免冲突
  • Select 无 status prop,用根元素 class is-error + index.scss 新增触发器红色边框,样式与 input-error 一致(--fms-danger + focus 光圈)
  • date 系列共享 date/index.scss(已 import),错误态样式集中加在此文件,覆盖 date/range/time 三类触发器
  • 校验时机用 touched 标记避免初始空值即报红:仅在提交后或值变化后才展示错误

设计风格

延续现有组件库的极简企业风:token 驱动的浅色/深色主题自适应,干净的白底卡片式演示面板。Form 组件本体强调信息层级清晰——横向布局 label 定宽右对齐与控件严格对齐,垂直布局上下堆叠留白一致;错误态用红色文字 + 红色边框 + focus 光圈,与 Input 现有校验样式统一;必填红星、辅助说明、错误提示三级信息通过颜色和字号区分主次。

页面规划

demo/form.vue 按现有 showcase 规范组织,包含 4 个功能区块:基础用法(横向)、纵向布局、自定义校验(validator 联动)、错误态联动(Select/DatePicker 红色边框演示),顶部统一 section-heading,底部提交/重置按钮用 Button 组件呈现。

Agent Extensions

Skill

  • antdv-next
  • 用途:实现 Form/FormItem 组件时,检索参考组件库中 Form 的 props/events/slots 与交互设计(必填星、错误态、布局细节)
  • 预期结果:确认 API 命名与交互细节对齐参考库的精简子集,避免遗漏关键行为
  • ui-ux-pro-max
  • 用途:demo/form.vue 演示页与表单视觉设计参考,确保错误态/必填星等视觉规范现代且统一
  • 预期结果:演示页布局清晰、视觉层级合理,符合组件库既有风格