Skip to content

Form - 表单

表单是用户和网站交互最重要的一部分。

表单有很多控件,这里选了几个简单的模拟实现,就单独整理写到这里了. 表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。

典型表单:

最基础的表单包括各种输入表单项,比如:

  • input
  • select
  • radio
  • checkbox

在每一个 form 组件中,你需要一个 form-item 字段作为输入项的容器,用于获取值与验证值。

按照原型图整理的简单需求:

  • 自定义UI
    • 整理可自定义
    • 用户可自定义渲染多种类型的表单元素
    • 用户可自定义提交区域内容
  • 验证时机
    • 表单元素默认blur时验证,可自定义
    • 整个表单在点击提交时应全部验证
  • 验证规则
    • 每个input可配置多条规则
    • 规则可自定义

组件结构设计

js
const formOptions = {
  name: { key: 'name', value: '', rules: [], ... }
  [otherKey]: { key: 'xxx', value: '', rules: [], ... }
}

<Form :options="formOptions" />

// 但这种用法过于繁杂,不灵活,在使用上体现不出结构,会让js臃肿,所以用slot的形式
<Form>
  <FormItem label="label" name="name">
    <Input />
  </FormItem>
  <FormItem label="label2" name="name2">
    <Select />
  </FormItem>
</Form>

开发步骤:

  1. 根据结构,实现基础布局,完成demo
  2. 添加初始化数据,绑定数据
  3. 添加验证
  4. 事件交互,验证等
  5. 不断完善

验证思路

验证类型:

  • 表单Form整体验证
  • 单个表单FormItem的验证

表单中每项循环验证一次 every 即为表单验证结果

单个验证实现思路:

  • 从父组件Form获取对应option、value
  • 在FormItem组件中实现

第三方库:async-validator


Input - 输入框

表单是用户和网站交互最重要的一部分

文档地址:

input: https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input

textarea: https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/textarea

需求分析

  • 支持 input / textarea
  • 支持不同大小
  • 应可以一键清空
  • 支持切换是否不可见(密码或敏感信息输入)
  • 支持自定义前缀、后缀

分析出来需要添加的原生属性:

  • disabled 已添加
  • placeholder 当没有预设值时,出现的文字
  • readonly 布尔值,若存在,其中的值不可编辑
  • autocomplete 除了 checkbox、radio 和按钮外,表单自动填充特性提示
  • autofocus 一个布尔属性,若存在,表示当页面加载完毕该 input 自动拥有焦点
  • form 一个字符串,指定该输入与之相关的表单元素

TDD 开发遇到的一些小问题

在大部分情况下,它能很好地运行,但由于 jsdom 使用模拟 DOM 环境,会和浏览器真实环境有差别,在一些功能上出现问题

不必纠结完全一致。实际以 demo 浏览器上的表现即可

Switch

并不是一个标准的 Form 组件

  • 功能类似 checkbox
  • 样式独特

一开始 modelValue 只支持 boolean,但这不能满足一定的场景。这里为了扩展,我们增加 string 和 number 的类型支持

扩展 activeText 和 inactiveText

表单组件设计要特别注意和原生表单元素的配合,尽可能实现良好的可访问性

Select

需求分析

进阶版的Dropdown,Input组件和Tooltip组件的组合。类似原生Select,具有以下最基本功能:

  • 点击展开下拉选项菜单
  • 点击菜单中的某一项,下拉菜单关闭
  • Select获取选中状态,并且填充对应的选项

其他扩展功能:

  • 可清空选项:hover后 同Input
  • 可自定义模版。可自定义下单菜单的选项格式
    • 思路 使用render函数
    • 这里我们用之前定义的 RenderVnode 即可 (e: SelectOption) => VNode
  • 可筛选选项,可切换成Input允许输入并过滤下拉选项
  • 支持远程搜索:类似联想,可根据输入字符发送请求,渲染返回的内容作为选项

实现筛选功能

思路:

  • 在本地存储一个可变的响应式对象
  • 在input时重新计算,渲染新的值

优化:

  • 再次选择需要清空input
  • 再次选择改善placeholder显示,显示当前选中的值

支持远程搜索

思路:

在input输入过程中,根据用户传入的remote处理方式,发请求并且渲染结果

优化:

  • debounce防抖 (减少不必要的请求)