Form

优质
小牛编辑
136浏览
2023-12-01

1.7.0 新增

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

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

示例

  • 默认配置使用

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

    <cube-form
      :model="model"
      :schema="schema"
      :immediate-validate="false"
      :options="options"
      @validate="validateHandler"
      @submit="submitHandler"
      @reset="resetHandler"></cube-form>
    
    export default {
      data() {
        return {
          validity: {},
          valid: undefined,
          model: {
            checkboxValue: false,
            checkboxGroupValue: [],
            inputValue: '',
            radioValue: '',
            rateValue: 0,
            selectValue: 2018,
            switchValue: true,
            textareaValue: '',
            uploadValue: []
          },
          schema: {
            groups: [
              {
                legend: '基础',
                fields: [
                  {
                    type: 'checkbox',
                    modelKey: 'checkboxValue',
                    props: {
                      option: {
                        label: 'Checkbox',
                        value: true
                      }
                    },
                    rules: {
                      required: true
                    },
                    messages: {
                      required: 'Please check this field'
                    }
                  },
                  {
                    type: 'checkbox-group',
                    modelKey: 'checkboxGroupValue',
                    label: 'CheckboxGroup',
                    props: {
                      options: ['1', '2', '3']
                    },
                    rules: {
                      required: true
                    }
                  },
                  {
                    type: 'input',
                    modelKey: 'inputValue',
                    label: 'Input',
                    props: {
                      placeholder: '请输入'
                    },
                    rules: {
                      required: true
                    },
                    // validating when blur
                    trigger: 'blur'
                  },
                  {
                    type: 'radio-group',
                    modelKey: 'radioValue',
                    label: 'Radio',
                    props: {
                      options: ['1', '2', '3']
                    },
                    rules: {
                      required: true
                    }
                  },
                  {
                    type: 'select',
                    modelKey: 'selectValue',
                    label: 'Select',
                    props: {
                      options: [2015, 2016, 2017, 2018, 2019, 2020]
                    },
                    rules: {
                      required: true
                    }
                  },
                  {
                    type: 'switch',
                    modelKey: 'switchValue',
                    label: 'Switch',
                    rules: {
                      required: true
                    }
                  },
                  {
                    type: 'textarea',
                    modelKey: 'textareaValue',
                    label: 'Textarea',
                    rules: {
                      required: true
                    },
                    // debounce validate
                    // if set to true, the default debounce time will be 200(ms)
                    debounce: 100
                  }
                ]
              },
              {
                legend: '高级',
                fields: [
                  {
                    type: 'rate',
                    modelKey: 'rateValue',
                    label: 'Rate',
                    rules: {
                      required: true
                    }
                  },
                  {
                    type: 'upload',
                    modelKey: 'uploadValue',
                    label: 'Upload',
                    events: {
                      'file-removed': (...args) => {
                        console.log('file removed', args)
                      }
                    },
                    rules: {
                      required: true,
                      uploaded: (val, config) => {
                        return Promise.all(val.map((file, i) => {
                          return new Promise((resolve, reject) => {
                            if (file.uploadedUrl) {
                              return resolve()
                            }
                            // fake request
                            setTimeout(() => {
                              if (i % 2) {
                                reject(new Error())
                              } else {
                                file.uploadedUrl = 'uploaded/url'
                                resolve()
                              }
                            }, 1000)
                          })
                        })).then(() => {
                          return true
                        })
                      }
                    },
                    messages: {
                      uploaded: '上传失败'
                    }
                  }
                ]
              },
              {
                fields: [
                  {
                    type: 'submit',
                    label: 'Submit'
                  },
                  {
                    type: 'reset',
                    label: 'Reset'
                  }
                ]
              }
            ]
          },
          options: {
            scrollToInvalidField: true,
            layout: 'standard' // classic fresh
          }
        }
      },
      methods: {
        submitHandler(e) {
          e.preventDefault()
          console.log('submit', e)
        },
        validateHandler(result) {
          this.validity = result.validity
          this.valid = result.valid
          console.log('validity', result.validity, result.valid, result.dirty, result.firstInvalidFieldIndex)
        },
        resetHandler(e) {
          console.log('reset', e)
        }
      }
    }
    

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

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

  • 自定义使用

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

    <cube-form :model="model" @validate="validateHandler" @submit="submitHandler">
      <cube-form-group>
        <cube-form-item :field="fields[0]"></cube-form-item>
        <cube-form-item :field="fields[1]"></cube-form-item>
        <cube-form-item :field="fields[2]">
          <cube-button @click="showDatePicker">{{model.dateValue || 'Please select date'}}</cube-button>
          <date-picker ref="datePicker" :min="[2008, 8, 8]" :max="[2020, 10, 20]" @select="dateSelectHandler"></date-picker>
        </cube-form-item>
      </cube-form-group>
      <cube-form-group>
        <cube-button type="submit">Submit</cube-button>
      </cube-form-group>
    </cube-form>
    
    // province, city, area
    // select component
    const PCA = {
      props: {
        value: {
          type: Array,
          default() {
            return []
          }
        }
      },
      data() {
        return {
          selected: []
        }
      },
      render(createElement) {
        return createElement('cube-button', {
          on: {
            click: this.showPicker
          }
        }, this.selected.length ? this.selected.join(' ') : 'placeholder')
      },
      mounted() {
        this.picker = this.$createCascadePicker({
          title: 'PCA Select',
          data: cityData,
          selectedIndex: this.value,
          onSelect: this.selectHandler
        })
      },
      methods: {
        showPicker() {
          this.picker.show()
        },
        selectHandler(selectedVal, selectedIndex, selectedTxt) {
          this.selected = selectedTxt
          this.$emit('input', selectedVal)
        }
      }
    }
    export default {
      data() {
        return {
          validity: {},
          valid: undefined,
          model: {
            inputValue: '',
            pcaValue: [],
            dateValue: ''
          },
          fields: [
            {
              type: 'input',
              modelKey: 'inputValue',
              label: 'Input',
              props: {
                placeholder: '请输入'
              },
              rules: {
                required: true
              }
            },
            {
              component: PCA,
              modelKey: 'pcaValue',
              label: 'PCASelect',
              rules: {
                required: true
              },
              messages: {
                required: '请选择'
              }
            },
            {
              modelKey: 'dateValue',
              label: 'Date',
              rules: {
                required: true
              }
            }
          ]
        }
      },
      methods: {
        submitHandler(e) {
          console.log('submit')
        },
        validateHandler(result) {
          this.validity = result.validity
          this.valid = result.valid
          console.log('validity', result.validity, result.valid, result.dirty, result.firstInvalidFieldIndex)
        },
        showDatePicker() {
          this.$refs.datePicker.show()
        },
        dateSelectHandler(selectedVal) {
          this.model.dateValue = new Date(selectedVal[0], selectedVal[1] - 1, selectedVal[2]).toDateString()
        }
      },
      components: {
        DatePicker
      }
    }
    

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

    • 自定义问卷场景

    你可以利用 Form 组件的特性轻松实现类似问卷这种场景表单,组件示例源代码:https://github.com/didi/cube-ui/tree/dev/example/components/questionnaire

    <demo-questionnaire
      :tip="tip"
      :questions="questions"
      :submit="submit"
      @submit="submitHandler"
    />
    
    // source
    // https://github.com/didi/cube-ui/tree/dev/example/components/questionnaire/questionnaire.vue
    import DemoQuestionnaire from 'example/components/questionnaire/questionnaire.vue'
    export default {
      data() {
        return {
          tip: '请配合如实填写问卷,确保xxxx相关文案',
          questions: [
            {
              type: 'switch',
              model: 'switch',
              title: '询问是否?'
              // required: true
            },
            {
              type: 'input',
              model: 'input',
              title: '输入',
              options: {
                placeholder: '请输入'
              },
              on: 'switch',
              required: true
            },
            {
              type: 'date',
              model: 'date',
              title: '日期',
              options: {
                // min: '2020-01-01',
                // max: '2020-02-18'
              },
              required: true
            },
            {
              type: 'time',
              model: 'time',
              title: '时间',
              options: {
                min: '01:00',
                max: '23:59'
              },
              required: true
            },
            {
              type: 'select',
              model: 'select',
              title: '选择',
              options: [
                'option1',
                'option2',
                'option3'
              ],
              required: true
            },
            {
              type: 'radio',
              model: 'radio',
              title: '单选',
              options: [
                '单选1',
                '单选2',
                '单选3'
              ],
              required: true
            },
            {
              type: 'checkbox',
              model: 'checkbox',
              title: '多选',
              options: [
                '多选1',
                '多选2',
                '多选3'
              ],
              required: true
            },
            {
              type: 'textarea',
              model: 'textarea',
              title: '多行文本',
              on: {
                model: 'checkbox',
                options: ['多选1', '多选3']
              },
              required: true
            },
            {
              type: 'checkbox',
              row: true,
              model: 'checkbox2',
              title: '多选-横',
              options: [
                '多选-横1',
                '多选-横2',
                '多选-横3'
              ],
              required: true
            },
            {
              type: 'tel',
              model: 'tel',
              title: '手机号',
              options: {
                placeholder: '请输入手机号'
              },
              required: true
            },
            {
              type: 'rate',
              model: 'rate',
              title: '级别',
              options: {
                max: 10
              },
              required: true
            },
            {
              type: 'city',
              model: 'city',
              title: '城市',
              required: true
            },
            {
              type: 'upload',
              model: 'upload',
              title: '上传',
              options: {
                action: '//jsonplaceholder.typicode.com/photos/',
                max: 2
              },
              required: true
            },
            {
              type: 'agreement',
              model: 'agreement',
              options: {
                text: '请同意',
                link: {
                  text: '《xx协议》',
                  href: 'https://github.com/didi/cube-ui'
                },
                desc: '说明:本人承诺xx xxxxx xxx xx。'
              },
              required: true,
              errMsg: '请同意协议'
            }
          ],
          submit: {
            text: 'Submit'
          }
        }
      },
      components: {
        DemoQuestionnaire
      },
      methods: {
        submitHandler(model) {
          console.log('submit', model)
        }
      }
    }
    

Props 配置

CubeForm

参数说明类型可选值默认值
model数据源Object-{}
schema生成表单依赖的模式Object-{}
immediateValidate初始化时是否立即校验Booleantrue/falsefalse
action表单 Form action 的值String-undefined
options配置项Object-{
scrollToInvalidField: false,
layout: 'standard' // or: classic
submitAlwaysValidate1.12.36+提交表单时是否总校验所有字段Booleantrue/falsefalse
  • schema 子配置项

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

    • 无分组

      直接包含 fields 即可:

      {
        fields: [
          {
            type: 'input',
            modelKey: 'inputValue',
            label: 'Input'
          },
          // ...
        ]
      }
      
    • 有分组

      可以设置 groups

      {
        groups: [
          {
            legend: 'Group 1'
            fields: [
              {
                type: 'input',
                modelKey: 'inputValue',
                label: 'Input'
              },
              // ...
            ]
          },
          {
            legend: 'Group 2'
            fields: [
              {
                type: 'input',
                modelKey: 'inputValue',
                label: 'Input'
              },
              // ...
            ]
          }
        ]
      }
      

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

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

    参数说明类型可选值默认值
    scrollToInvalidField是否默认滚动到第一个无效字段位置Booleantrue/falsefalse
    layout表单何种布局方式Stringstandard/classic/freshstandard

CubeFormGroup

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

CubeFormItem

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

事件

事件名说明参数1参数2参数3
submit表单校验通过后触发此事件,如果只有同步校验,则不会阻止默认行为,而如果包含了异步校验,则默认就会阻止默认行为e - 事件对象model 值只包含存在的字段的 model 值1.12.30+
reset表单重置事件e - 事件对象--
validate表单校验事件参数结构如下:
{
validity,
valid,
invalid,
dirty,
firstInvalidFieldIndex
}
--
valid表单校验成功触发validity 校验结果--
invalid表单校验失败触发validity 校验结果--
  • validate 事件的参数

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

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

实例方法

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

最后更新:

类似资料

  • 值的立方体只是值与自身相乘的三倍。 For example, 2的立方体是(2 * 2 * 2)= 8。 算法 (Algorithm) 该程序的算法简单易行 - START Step 1 → Take integer variable A Step 2 → Multiply A three times Step 3 → Display result as Cube STOP 伪

  • Cube 是一个开源的基于 MongoDB 的数据分析工具 Cube 的收集器接收事件并将这些事件保持在 MongoDB 中。你可通过 UDP、HTTP POST 或者 WebSockets 来发送事件。同时 Cube 内置支持接受来自 collectd 的事件。

  • 在前面的章节中,我们已经看到了如何绘制三角形并旋转它。 现在,在本章中,您可以了解如何使用3D立方体,如何旋转它,如何在其上附加图像。 同样,本章提供了绘制3D立方体并为其应用颜色并将图像附加到其上的示例。 下面给出了绘制三维立方体并为其应用颜色的程序。 import java.awt.DisplayMode; import javax.media.opengl.GL2; import javax

  • 找到给定数字是偶数或奇数,是一个经典的C程序。 我们将在C中学习使用条件语句if-else 。 算法 (Algorithm) 这个程序的算法很简单 - START Step 1 → Take integer variable A Step 2 → Assign value to the variable Step 3 → Perform A modulo 2 and check

  • cube-flowable 工作流引擎旨在打造一套零代码、领先、且快速实用的引擎工具,助力开发者在面对工作流开发任务时,除去学习工作流框架知识和API的学习成本且不去关心工作流是什么技术,无需了解学习,安装使用cube-flowable工作流引擎并应用落地。 此工作流引擎是零代码或低代码的工作流引擎,安装配置开箱即可使用,完全适用于中国国情的工作流引擎。主要特点包括: 在线拖拽可视化业务表单,并自

  • cube-ui 是由滴滴开源的基于 Vue.js 实现的移动端组件库。 功能特性 质量可靠 由滴滴内部组件库精简提炼而来,经历了业务一年多的考验,并且每个组件都有充分单元测试,为后续集成提供保障。 体验极致 以迅速响应、动画流畅、接近原生为目标,在交互体验方面追求极致。 标准规范 遵循统一的设计交互标准,高度还原设计效果;接口标准化,统一规范使用方式,开发更加简单高效。 扩展性强 支持按需引入和后