表单

背景

表单是客户端Weex开发常见的页面, 尤其特别在toB的项目中, 收集提交一些数据是非常高频且重要的业务. 相比于其他页面表单本身有一定的特性, 比如一定存在的提交按钮 竖向排列的UI来区分不同的数据字段 必要数据的必填项 输入错误的提示等等, 所以它本身是可以进行抽象封装的.
在此前的表单业务开发当中, 由于考虑范围只在当次那个业务当中, 所以整个表单方向代码复用率低, 扩展性低. 此次方案, 主要思路是从过往的表单业务中归纳分析, 抱着以统一处理所有相关业务的思想, 分类并逐步完善与表单相关的所有业务, 技术上追求在表单业务应有的规范下, 一套框架可以满足当前和以后所有的表单.

目标

落地客户端Weex表单框架, 和设计共同维护表单业务规范, 能在未来的迭代中不断完善和调优

做法

表单本身涉及技术点较多, 所以需要将相关联的技术点进行汇总统一, 大的方向上划分出分类, 每个分类单独进行调研和处理

分类

表单规范
规范表单实现, 规范表单数据处理
表单组件和布局
负责整体UI页面的搭建
表单验证和错误处理
负责统一处理必填项 输入项校验 错误提示等
常见业务的处理
比如关闭时的弹框提示 时间选择 日期选择组件等

表单规范

表单数据

对于表单内的数据, 例如输入的input名字, 选择的性别男女sex等. 所有因为表单组件产生或修改的数据, 都统一包装到页面的一个对象内, 对象名字为formData, 每一项对应的数据内容要有相应的注释, 不应该包含其他无关属性. 数据格式的设计应该按照表单页面结构或者顺序设计, 不应该按照后台接口结构设计.

表单数据的处理: 提交和回填

遵循表单数据规范后, 数据提交就是将formData数据转换成后台接口body结构, 数据回填就是将后台返回body转换成formData, 所以统一命名方法为: formDataToBody(),bodyToFormData(body)

  1. //自定义组件, (通过v-model双向绑定来传递数据)
  2. <fg-form-xxx v-model="form.data.selectAge"></fg-form-xxx>
  3. //data, (所有数据放到formData中, 并且注释)
  4. formData: {
  5. name: '', //姓名
  6. sex: 0, //性别,默认男
  7. selectAge:0 //年龄
  8. }
  9. //method
  10. formDataToBody(){
  11. return {
  12. upPhotos: this.fomrData.imageUrl
  13. ...
  14. }
  15. }
  16. bodyToFormData(body){
  17. this.formData.imageUrl = body.upPhotos
  18. ...
  19. }

表单组件

表单组件要支持v-model, 并且尽可能的只使用v-mode来传递和配置数据
表单页面的组件应该尽可能使用已有组件, 避免重复造相似的轮子, 对于业务上的不同, 应该尽可能通过配置去扩展组件来达到需求效果
表单组件需要配备相应的文档说明, 且有demo

fg-form

image.pngimage.png

属性

参数 说明 类型 作用范围 默认值
data 所有表单数据 Object form
rules 所有表单数据的验证规则 Array form
containterStyle scroller组件的style Object form
canGestureClose 能否手势返回 Boolaen form false
以下属性作用于子元素fg-form-item, 非Form本身
position 容器在右使用:left,right
容器在下使用:top
left和right区别是label对齐方式
String 一级Item 默认left. 可选left, right, top
labelWidth label域的宽度,label存在时有效 String 所有Item left,right时:77wx
top时: auto
labelHeight label域的高度,label存在时有效 String 所有Item left,right默认:44wx
top默认: auto
height 整个Item的高度, 非固定高度一般使用labelHeight代替 String 所有Item auto
required label是否显示红色必填 Boolean 所有Item false
marginTop 上间距 String 一级Item 0wx
marginRight 右间距 String 一级Item 0wx
marginBottom 下间距 String 一级Item 0wx
marginLeft 左间距 String 一级Item 16wx
paddingTop 上内间距 String 一级Item 0wx
paddingRight 右内间距 String 一级Item 16wx
paddingBottom 下内间距 String 一级Item 0wx
paddingLeft 左内间距 String 一级Item 0wx
disabled 整个元素的disabled状态 Boolean 所有Item false
slotDisabled 元素插槽的disabled状态 Boolean 所有Item false
disabledOpacity disbled时的透明度 Number 所有Item 0.4
backgroundColor 除上下desc部分,剩余部分背景颜色 String 所有Item white
showLine 是否显示下划线 Boolean 最深Item false
lineLeftRightMargin 下划线左右边距 Array 最深Item [‘16wx’,’0wx’]
rightSlotWidth 右侧插槽宽度 String 最深Item 0wx

fg-form-item

属性

参数 说明 类型 默认值
labelWidth label域的宽度, label存在时才有效 String left,right时:77wx
top时: auto
labelHeight label域的高度, label存在时才有效 String 44wx
rightSlotWidth 右侧插槽宽度 String 0wx
position 容器在右使用:left,right
容器在下使用:top
left和right区别是label对齐方式
String 默认left.
可选left, right, top
inline 行内模式(插槽row,并且内部的item会被自动均分) Boolean false
height 整个容器的高度, 非必要建议使用labelHeight撑开 String auto
label label的标题内容 String
labelRichConfig label富文本属性 Array
subLabel label的副标题内容 String
subLabelRichConfig label的副标题富文本属性 Array
required label是否显示必填 Boolean false
requiredString 必填label的文本内容 String *
topDesc 顶部描述 String
topDescRichConfig 顶部描述富文本属性 Array
bottomDesc 底部描述 String
bottomDescRichConfig 底部描述富文本属性 Array
disabled 整个元素的disabled状态 Boolean false
slotDisabled 元素插槽的disabled状态 Boolean false
disabledOpacity disbled时的透明度 Number 0.4
showLine 是否显示下划线 Boolean false
lineLeftRightMargin 下划线左右边距 Array [‘16wx’,’0wx’]
backgroundColor 除上下desc部分,剩余部分背景颜色 String white
marginTop 上间距 String 0wx
marginRight 右间距 String 0wx
marginBottom 下间距 String 0wx
marginLeft 左间距 String 16wx
paddingTop 上内间距 String 0wx
paddingRight 右内间距 String 16wx
paddingBotton 下内间距 String 0wx
paddingLeft 左内间距 String 0wx
containterStyle 自定义容器的style Object
contentStyle 自定义容器的style Object
labelContainterStyle 自定义容器的style Object
labelStyle 自定义容器的style Object
subLabelStyle 自定义容器的style Object
requiredStyle 自定义容器的style Object
slotContainterStyle 自定义容器的style Object
lineStyle 自定义容器的style Object
topDescContainter 自定义容器的style Object
topDescLabelStyle 自定义容器的style Object
bottomDescContainter 自定义容器的style Object
bottomDescLabelStyle 自定义容器的style Object
baseContentContainterStyle 自定义容器的style Object
baseContentStyle 自定义容器的style Object
contentRightStyle 自定义容器的style Object
labelSuffixStyle 自定义容器的style Object
labelPrefixStyle 自定义容器的style Object
labelContentStyle 自定义容器的style Object

插槽

slot名字 说明
default 主要内容插槽
topDesc 顶部描述插槽
bottomDesc 底部描述插槽
labelPrefix 文本域前插槽
labelSuffix 文本域后插槽

方法

事件名 参数 说明
_fatherFormItemClickEvent 插槽里的子组件使用,当Item被点击时,传递给一级children的事件
getDefaultSlotWidth 获取当前插槽的预估宽度, 当插槽内部组件需要知道当前宽度时使用, 宽度计算内部根据padding,margin等, 当自定义了style后不保证一定正确

注意事项

  • label域的label默认不支持换行, 如需换行, 请手动设置width
  • Item和Form支持的属性和事件内部使用$parent等来实现通讯, 所以当自己对组件进行包装时, 可能会影响通讯导致出现一些不可预知问题
  • 当Item插槽内部容器需要换行时, 例如flexwrap或者Text. 若使用的是top模式,且内部没有row容器嵌套则不需要给宽度,就可以正常换行. 若使用的是left/right模式, 需要手动通过getDefaultSlotWidth方法获取宽度, 并显示的给予对应组件,才可以正常换行

    demo:

    fg-form-layoutdemo(布局相关), fg-form-formdemo(属性相关)

fg-form-input

属性

名字 类型 默认值 说明
value String
文本内容, 外部v-model绑定值
placeholder String 占位文本
placeholderColor String #A2ABB3 占位文本颜色
autofocus Boolean false 是否焦点
fatherItemClickAutofocus Boolean true 当父组件是item时, 点击item自动让input获取焦点
height String 父级为Item时, 默认labelHeight或height,或form的height
父级非Item时, 默认auto
Input组件高度
maxLength Number 1000 最大文本长度
returnKeyType String 键盘return键类型
type String text 键盘类型
textAlign String right 文本对齐方式
fontSize String 字体大小
formatRule String 正则校验
recoverRule String 正则校验
containterStyle Object 容器Style
containterInputStyle Object 容器Style
inputStyle Object InputStyle
containterPrefix Object 前插槽Style
border Boolean false 是否显示Border
radius String 圆角
paddingLeft String 左内边距

插槽

名字 说明
prefix 整体前插槽, 在边框外部
inputPrefix input前插槽, 在边框内部
inputSuffix input后插槽, 在边框内部
suffix 整体后插槽, 在边框外部

表单验证和错误处理

使用方法

给form的data属性赋值formData, 给form的rules属性赋值formRules

示例

  1. //template
  2. <fg-form
  3. :data="formData"
  4. :rules="formRules"
  5. @validateChange="validateChange"
  6. >
  7. //...
  8. <fg-form>
  9. //script data
  10. formData: {
  11. name: '',
  12. age: undefined,
  13. sex: '',
  14. }
  15. formRules: [
  16. {name: {required: true, msg: '请输入姓名'}}, //表示姓名必填
  17. {age: [
  18. {required: true, msg: '请输入年龄'}, //表示年龄必填,且在1~200范围内
  19. {min:1,max:200, msg:'年龄范围应在1岁到200岁之间'}
  20. ]},
  21. {sex: [
  22. {required: false}, //表示性别非必填, 若填写必须为男或女
  23. {enum:['男','女'], msg:'性别只能是男或女'}
  24. ]}
  25. ]
  26. //script methods
  27. // 校验结果回调
  28. validateChange(data){
  29. //当formData数据或者formRules变化时, 自动进行校验并回调结果
  30. //data结构 {validate: 校验结果, msg: 第一个失败的msg, info: 详细校验结果, channleId:当前channleId}
  31. }

注意事项

  1. fomRules中的属性必须是formData的子集, 且校验顺序内部是按formRules的集合顺序
  2. formRules的格式为: [ {属性1: Object或集合 } , {属性2: Object或集合 } ], 当只有一个校验规则时使用Object, 多个使用集合包裹起来. 每个Object只能有一种规则

    所有规则

    | key | value类型 | 说明 | | —- | —- | —- | | required | Boolaen | 是否必填.
    必填时: 有值才校验
    非必填时: 无值不校验, 有值才校验
    是否有值规则: undefine,null, 空集合, 空字符都是无值的 | | min, max | Number | min: 最小, max:最大. 可以只填其中一项
    注:
    当值类型为Number时, 校验的是值本身大小
    当值类型为String/Array时, 校验的是值长度 | | len | Number | 长度, 校验String/Array的固定长度 | | enum | Array | 限制值范围 | | whitespace | Boolean | 限制非空格 | | pattern | RegExp/String | 自定义正则校验 | | validator | function | 自定义方法校验, 带一个参数为当前值, 需要一个返回值Boolean |

规则提示

key value类型 说明
msg String 当校验失败时传递出来的错误提示文本

fg-form-button

包装自fg-button, 属性和方法同fg-button. 当它和fg-form同时存在时, 此button的disabled状态会自动关联校验结果, 即校验成功时高亮, 校验失败时不高亮, 且效验失败时点击button会自动提示第一个失败的msg信息.
当提交按钮在导航栏时, 可以直接将导航栏的type设为form, 右侧按钮即自动为fg-form-button.

demo

fg-form-validateform