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 | 初始化时是否立即校验 | Boolean | true/false | false |
action | 表单 Form action 的值 | String | - | undefined |
options | 配置项 | Object | - | { scrollToInvalidField: false, layout: 'standard' // or: classic |
submitAlwaysValidate1.12.36+ | 提交表单时是否总校验所有字段 | Boolean | true/false | false |
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
;以及特殊的submit
和reset
,它们两个会被转换为对应类型的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 - - key1.12.36+ 字段的唯一key,尤其适用在 schema 更新的场景中 String - - options
子配置项参数 说明 类型 可选值 默认值 scrollToInvalidField 是否默认滚动到第一个无效字段位置 Boolean true/false false layout 表单何种布局方式 String standard/classic/fresh standard
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 或 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 | 提交表单 | skipValidate, 默认 false,如果为 true 代表不校验 直接 submit1.12.2+ | - |
reset | 重置表单 | - | - |
validate(cb) | 校验表单 | cb: 校验完成后回调函数,主要用于异步校验场景,调用参数为 valid 的值 | 如果支持 Promise 的话返回值是 Promise 对象(只有 resolved 状态,值为 valid),否则 undefined |