Form

1.7.0 新增 从 1.8.0 开始支持blur 时才触发校验以及 debounce,同 Validator 一样也开始支持异步校验。

表单,包含各种输入组件以及对应的校验;我们可以通过数据驱动的方式来生成完成表单。

示例

默认配置使用

一个完整的包含所有的内置表单相关组件。

  1. <cube-form :model="model" :schema="schema" :immediate-validate="false" :options="options" @validate="validateHandler" @submit="submitHandler" @reset="resetHandler"></cube-form>
  1. export default {
  2. data() {
  3. return {
  4. validity: {},
  5. valid: undefined,
  6. model: {
  7. checkboxValue: false,
  8. checkboxGroupValue: [],
  9. inputValue: '',
  10. radioValue: '',
  11. rateValue: 0,
  12. selectValue: 2018,
  13. switchValue: true,
  14. textareaValue: '',
  15. uploadValue: []
  16. },
  17. schema: {
  18. groups: [
  19. {
  20. legend: '基础',
  21. fields: [
  22. {
  23. type: 'checkbox',
  24. modelKey: 'checkboxValue',
  25. props: {
  26. option: {
  27. label: 'Checkbox',
  28. value: true
  29. }
  30. },
  31. rules: {
  32. required: true
  33. },
  34. messages: {
  35. required: 'Please check this field'
  36. }
  37. },
  38. {
  39. type: 'checkbox-group',
  40. modelKey: 'checkboxGroupValue',
  41. label: 'CheckboxGroup',
  42. props: {
  43. options: ['1', '2', '3']
  44. },
  45. rules: {
  46. required: true
  47. }
  48. },
  49. {
  50. type: 'input',
  51. modelKey: 'inputValue',
  52. label: 'Input',
  53. props: {
  54. placeholder: '请输入'
  55. },
  56. rules: {
  57. required: true
  58. },
  59. // validating when blur
  60. trigger: 'blur'
  61. },
  62. {
  63. type: 'radio-group',
  64. modelKey: 'radioValue',
  65. label: 'Radio',
  66. props: {
  67. options: ['1', '2', '3']
  68. },
  69. rules: {
  70. required: true
  71. }
  72. },
  73. {
  74. type: 'select',
  75. modelKey: 'selectValue',
  76. label: 'Select',
  77. props: {
  78. options: [2015, 2016, 2017, 2018, 2019, 2020]
  79. },
  80. rules: {
  81. required: true
  82. }
  83. },
  84. {
  85. type: 'switch',
  86. modelKey: 'switchValue',
  87. label: 'Switch',
  88. rules: {
  89. required: true
  90. }
  91. },
  92. {
  93. type: 'textarea',
  94. modelKey: 'textareaValue',
  95. label: 'Textarea',
  96. rules: {
  97. required: true
  98. },
  99. // debounce validate
  100. // if set to true, the default debounce time will be 200(ms)
  101. debounce: 100
  102. }
  103. ]
  104. },
  105. {
  106. legend: '高级',
  107. fields: [
  108. {
  109. type: 'rate',
  110. modelKey: 'rateValue',
  111. label: 'Rate',
  112. rules: {
  113. required: true
  114. }
  115. },
  116. {
  117. type: 'upload',
  118. modelKey: 'uploadValue',
  119. label: 'Upload',
  120. events: {
  121. 'file-removed': (...args) => {
  122. console.log('file removed', args)
  123. }
  124. },
  125. rules: {
  126. required: true,
  127. uploaded: (val, config) => {
  128. return Promise.all(val.map((file, i) => {
  129. return new Promise((resolve, reject) => {
  130. if (file.uploadedUrl) {
  131. return resolve()
  132. }
  133. // fake request
  134. setTimeout(() => {
  135. if (i % 2) {
  136. reject(new Error())
  137. } else {
  138. file.uploadedUrl = 'uploaded/url'
  139. resolve()
  140. }
  141. }, 1000)
  142. })
  143. })).then(() => {
  144. return true
  145. })
  146. }
  147. },
  148. messages: {
  149. uploaded: '上传失败'
  150. }
  151. }
  152. ]
  153. },
  154. {
  155. fields: [
  156. {
  157. type: 'submit',
  158. label: 'Submit'
  159. },
  160. {
  161. type: 'reset',
  162. label: 'Reset'
  163. }
  164. ]
  165. }
  166. ]
  167. },
  168. options: {
  169. scrollToInvalidField: true,
  170. layout: 'standard' // classic fresh
  171. }
  172. }
  173. },
  174. methods: {
  175. submitHandler(e) {
  176. e.preventDefault()
  177. console.log('submit', e)
  178. },
  179. validateHandler(result) {
  180. this.validity = result.validity
  181. this.valid = result.valid
  182. console.log('validity', result.validity, result.valid, result.dirty, result.firstInvalidFieldIndex)
  183. },
  184. resetHandler(e) {
  185. console.log('reset', e)
  186. }
  187. }
  188. }

model 就是整个表单需要的数据源,schema 就是生成表单所定义的模式,immediate-validate 如果为 true 则初始时立即做校验,options 则是配置选项。

submit 校验成功后提交事件,validate 每次有数据校验更新的事件,reset 则是重置事件。

自定义使用

你可以选择使用自己自定义的组件甚至通过插槽来自定义结构和行为。

  1. <cube-form :model="model" @validate="validateHandler" @submit="submitHandler">
  2. <cube-form-group>
  3. <cube-form-item :field="fields[0]"></cube-form-item>
  4. <cube-form-item :field="fields[1]"></cube-form-item>
  5. <cube-form-item :field="fields[2]">
  6. <cube-button @click="showDatePicker">{{model.dateValue || 'Please select date'}}</cube-button>
  7. <date-picker ref="datePicker" :min="[2008, 8, 8]" :max="[2020, 10, 20]" @select="dateSelectHandler"></date-picker>
  8. </cube-form-item>
  9. </cube-form-group>
  10. <cube-form-group>
  11. <cube-button type="submit">Submit</cube-button>
  12. </cube-form-group>
  13. </cube-form>
  1. // province, city, area
  2. // select component
  3. const PCA = {
  4. props: {
  5. value: {
  6. type: Array,
  7. default() {
  8. return []
  9. }
  10. }
  11. },
  12. data() {
  13. return {
  14. selected: []
  15. }
  16. },
  17. render(createElement) {
  18. return createElement('cube-button', {
  19. on: {
  20. click: this.showPicker
  21. }
  22. }, this.selected.length ? this.selected.join(' ') : 'placeholder')
  23. },
  24. mounted() {
  25. this.picker = this.- createCascadePicker({
  26. title: 'PCA Select',
  27. data: cityData,
  28. selectedIndex: this.value,
  29. onSelect: this.selectHandler
  30. })
  31. },
  32. methods: {
  33. showPicker() {
  34. this.picker.show()
  35. },
  36. selectHandler(selectedVal, selectedIndex, selectedTxt) {
  37. this.selected = selectedTxt
  38. this.- emit('input', selectedVal)
  39. }
  40. }
  41. }
  42. export default {
  43. data() {
  44. return {
  45. validity: {},
  46. valid: undefined,
  47. model: {
  48. inputValue: '',
  49. pcaValue: [],
  50. dateValue: ''
  51. },
  52. fields: [
  53. {
  54. type: 'input',
  55. modelKey: 'inputValue',
  56. label: 'Input',
  57. props: {
  58. placeholder: '请输入'
  59. },
  60. rules: {
  61. required: true
  62. }
  63. },
  64. {
  65. component: PCA,
  66. modelKey: 'pcaValue',
  67. label: 'PCASelect',
  68. rules: {
  69. required: true
  70. },
  71. messages: {
  72. required: '请选择'
  73. }
  74. },
  75. {
  76. modelKey: 'dateValue',
  77. label: 'Date',
  78. rules: {
  79. required: true
  80. }
  81. }
  82. ]
  83. }
  84. },
  85. methods: {
  86. submitHandler(e) {
  87. console.log('submit')
  88. },
  89. validateHandler(result) {
  90. this.validity = result.validity
  91. this.valid = result.valid
  92. console.log('validity', result.validity, result.valid, result.dirty, result.firstInvalidFieldIndex)
  93. },
  94. showDatePicker() {
  95. this.- refs.datePicker.show()
  96. },
  97. dateSelectHandler(selectedVal) {
  98. this.model.dateValue = new Date(selectedVal[0], selectedVal[1] - 1, selectedVal[2]).toDateString()
  99. }
  100. },
  101. components: {
  102. DatePicker
  103. }
  104. }

可以通过 component 指定实现了 v-model 的自定义组件,例如示例中的 PCA 组件;也可以通过使用插槽自定义结构行为,比如示例中的日期选择。

Props 配置

CubeForm

参数 说明 类型 可选值 默认值
model 数据源 Object - {}
schema 生成表单依赖的模式 Object - {}
immediateValidate 初始化时是否立即校验 Boolean true/false false
action 表单 Form action 的值 String - undefined
options 配置项 Object - {scrollToInvalidField: false, layout: ‘standard’ // or: classic

schema 子配置项

模式用于定义表单中的各个字段,可以选择是否分组。

无分组

直接包含 fields 即可:

  1. {
  2. fields: [
  3. {
  4. type: 'input',
  5. modelKey: 'inputValue',
  6. label: 'Input'
  7. },
  8. // ...
  9. ]
  10. }

有分组

可以设置 groups:

  1. {
  2. groups: [
  3. {
  4. legend: 'Group 1'
  5. fields: [
  6. {
  7. type: 'input',
  8. modelKey: 'inputValue',
  9. label: 'Input'
  10. },
  11. // ...
  12. ]
  13. },
  14. {
  15. legend: 'Group 2'
  16. fields: [
  17. {
  18. type: 'input',
  19. modelKey: 'inputValue',
  20. label: 'Input'
  21. },
  22. // ...
  23. ]
  24. }
  25. ]
  26. }

不管有没有分组,我们都需要使用 fields 定义表单字段,其中每一项可以有如下属性:

参数 说明 类型 可选值 默认值
type 字段类型 String 默认内置的可选类型组件有:button, checkbox, checkbox-group, input, radio, radio-group, rate, select, switch, textarea, upload;以及特殊的 submitreset,它们两个会被转换为对应类型的 button -
component 字段使用的自定义组件,替换 type,该组件组件实现 v-model Object/String - -
modelKey 在表单的 model 数据源对象中所对应的 key 名字 String - -
label 字段的标签值 String - -
props type 对应的组件或者自定义组件 component 所需要的 props Object - -
events1.8.0+ type 对应的组件或者自定义组件 component 的事件回调 Object - -
rules 字段的校验规则,参见 Validator Object - -
trigger1.8.0+ 如果设置为 ‘blur’ 那么则会在离焦后校验 String blur/change -
debounce1.8.0+ 控制校验节奏,值为时间,单位 ms。如果 trigger 设置为 blur 则此项配置不生效 Number/Boolean >= 0,如果设置为 true,那么时间就是 200(ms) -
messages 字段的校验消息,参见 Validator String - -

CubeFormGroup

参数 说明 类型 可选值 默认值
legend 分组名字 String - ‘’
fields 该组内所包含的字段集合 Array - []

CubeFormItem

参数 说明 类型 可选值 默认值
field 字段数据 Object - -

事件

事件名 说明 参数1 参数2
submit 表单校验通过后触发此事件 e - 事件对象 model 值
reset 表单重置事件 e - 事件对象 -
validate 表单校验事件 参数结构如下:{validity, valid, invalid, dirty, firstInvalidFieldIndex} -
valid 表单校验成功触发 validity 校验结果 -
invalid 表单校验失败触发 validity 校验结果 -

validate 事件的参数

参数 说明 类型
validity 校验结果 Object
valid 校验合法,如果还没校验则为 undefined,一旦校验则为 true 或 false Boolean/Undefined
invalid 校验不合法,如果还没校验则为 undefined,一旦校验则为 true 或 false Boolean
dirty 表单处于 dirty 状态,也就意味着数据源发生了变化 Boolean
firstInvalidFieldIndex 第一个校验不合法的字段索引值 Number

校验结果 validity 对象

参数 说明 类型
valid 校验是否合法 Boolean/Undefined
result 校验结果,类似于:
{
 required: {
  valid: false,
  invalid: true,
  message: ‘Required.’
 }
}
Object
dirty 数据是否是已经更新过的 Boolean

实例方法

方法名 说明 参数 返回值
submit 提交表单 - -
reset 重置表单 - -
validate(cb) 校验表单 cb: 校验完成后回调函数,主要用于异步校验场景,调用参数为 valid 的值 如果支持 Promise 的话返回值是 Promise 对象(只有 resolved 状态,值为 valid),否则 undefined

原文:

https://didi.github.io/cube-ui/#/zh-CN/docs/form