19 KiB
Forms 表单
代码块:
uForms
、uni-forms-item
关联组件:uni-forms-item
、uni-easyinput
、uni-data-checkbox
、uni-group
。
uni-app的内置组件已经有了 <form>
组件,用于提交表单内容。
然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,uni ui
又基于 <form>
组件封装了 <uni-forms>
组件,内置了表单验证功能。
<uni-forms>
提供了 rules
属性来描述校验规则、<uni-forms-item>
子组件来包裹具体的表单项,以及给原生或三方组件提供了 binddata()
来设置表单值。
每个要校验的表单项,不管input还是checkbox,都必须放在<uni-forms-item>
组件中,且一个<uni-forms-item>
组件只能放置一个表单项。
<uni-forms-item>
组件内部预留了显示error message的区域,默认是在表单项的底部。
另外,<uni-forms>
组件下面的各个表单项,可以通过<uni-group>
包裹为不同的分组。同一<uni-group>
下的不同表单项目将聚拢在一起,同其他group保持垂直间距。<uni-group>
仅影响视觉效果。
为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
- 组件需要依赖
sass
插件 ,请自行手动安装focus
属性在开发者工具从不生效,需要真机测试resetFields
方法不会重置原生组件和三方组件的值- 如果配置
validateTrigger
属性为bind
且表单域组件使用input
事件触发会耗损部分性能,请谨慎使用- 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
平台差异说明
暂不支持在nvue页面中使用
安装方式
本组件符合easycom规范,HBuilderX 2.5.5
起,只需将本组件导入项目,在页面template
中即可直接使用,无需在页面中import
和注册components
。
如需通过npm
方式使用uni-ui
组件,另见文档:https://ext.dcloud.net.cn/plugin?id=55
基本用法
uni-forms
组件通常用来做表单校验和提交。每一个 uni-forms-item
是它的一个表单域组件,用来承载表单具体内容,uni-forms-item
中可以嵌套 uni-easyinput
、uni-data-checkbox
和 uni-app内置的表单组件 ,不过 uni-app 的内置表单组件需要通过 binddata
或者 uni-forms
提供的 setValue
方法,将内容与 uni-forms
关联,才可完成表单的校验与提交(详见后文表单校验
部分)
- 如需
submit
事件返回表单值,必须要指定name
属性
<template>
<view class="">
<uni-forms :value="formData" ref="form">
<uni-forms-item label="姓名" name="name">
<uni-easyinput type="text" v-model="formData.name" placeholder="请输入姓名" />
</uni-forms-item>
<uni-forms-item required name="hobby" label="兴趣爱好">
<uni-data-checkbox multiple v-model="formData.hobby" :localdata="hobby"/>
</uni-forms-item>
<uni-forms-item label="年龄" name="age">
<input type="text" v-model="formData.age" placeholder="请输入年龄" @input="binddata('age',$event.detail.value)" />
</uni-forms-item>
<button @click="submitForm">Submit</button>
</uni-forms>
</view>
</template>
export default {
data() {
return {
formData:{
name:'',
age:''
},
hobby: [{
text: '足球',
value: 0
}, {
text: '篮球',
value: 1
}, {
text: '游泳',
value: 2
}]
}
},
methods: {
submitForm(form) {
// 手动提交表单
this.$refs.form.submit().then((res)=>{
console.log('表单返回得值:', res)
})
}
}
}
表单校验
表单校验还可以直接通过 uniCloud web 控制台
快速根据 schema
自动生成表单维护界面,比如新建页面和编辑页面,自动处理校验规则,更多参考DB Schema
如何使用
uni-forms
需要通过rules
属性传入约定的校验规则(下文会详细描述)uni-forms
需要绑定value属性,值为表单的key\value 组成的对象uni-forms-item
需要设置name
属性为当前字段名,字段为String
类型而非变量- 如果使用
uni-easyinput
和uni-data-checkbox
等关联组件,只需绑定 v-model,无需其他操作 - 如果使用原生 input、checkbox 或三方组件等,只需要给组件绑定
binddata
方法即可触发表单校验,无需绑定事件到methods
中 binddata('name',$event.detail.value,'form')"
方法接受三个值,- 第一个参数传入当前表单组件所在的 name,同当前父组件
uni-forms-item
绑定属性name
的值 - 第二个参数传入需要校验的值,内置组件可以通过
$event.detail.value
获取到组件的返回值,自定义组件传入需要校验的值即可 - 第三个参数传入
uni-forms
组件绑定属性ref
的值,通常在多表单的时候需要传入,用来区分表单,如页面中仅有一个uni-forms
可忽略
- 第一个参数传入当前表单组件所在的 name,同当前父组件
- 如果内置
binddata
方法无法满足需求,在当前页面的methods
中复写此方法即可,复写此方法需要调用uni-forms
的setValue
来触发表单校验 - 通过
button
按钮调用uni-forms
的submit
事件来校验并提交整个表单
<template>
<view>
<uni-forms ref="form" :value="formData" :rules="rules">
<uni-forms-item label="姓名" name="name">
<uni-easyinput type="text" v-model="formData.name" placeholder="请输入姓名" />
</uni-forms-item>
<uni-forms-item label="邮箱" name="email">
<input class="input" v-model="formData.email" type="text" placeholder="请输入用户名" @input="binddata('email',$event.detail.value)" />
</uni-forms-item>
<button @click="submit">Submit</button>
</uni-forms>
</view>
</template>
export default {
data() {
return {
formData: {
name: 'LiMing',
email: 'dcloud@email.com'
},
rules: {
// 对name字段进行必填验证
name: {
rules: [{
required: true,
errorMessage: '请输入姓名',
},
{
minLength: 3,
maxLength: 5,
errorMessage: '姓名长度在 {minLength} 到 {maxLength} 个字符',
}
]
},
// 对email字段进行必填验证
email: {
rules: [{
format: 'email',
errorMessage: '请输入正确的邮箱地址',
}]
}
}
}
},
methods: {
/**
* 复写 binddata 方法,如果只是为了校验,无复杂自定义操作,可忽略此方法
* @param {String} name 字段名称
* @param {String} value 表单域的值
*/
// binddata(name,value){
// 通过 input 事件设置表单指定 name 的值
// this.$refs.form.setValue(name, value)
// },
// 触发提交表单
submit() {
this.$refs.form.submit().then(res=>{
console.log('表单数据信息:', res);
}).catch(err =>{
console.log('表单错误信息:', err);
})
}
}
}
校验规则
校验规则接受一个 Object
类型的值,通过传入不同的规则来表示每个表单域的值该如何校验
对象的 key
表示当前表单域的字段名,value
为具体的校验规则
以下为 value
所包含的内容:
属性名 | 类型 | 说明 |
---|---|---|
rules | Array | 校验规则,见下方 rules 属性说明 |
validateTrigger | String | 表单校验时机 |
label | String | 当前表单域的字段中文名,多用于 errorMessage 的显示,可不填 |
rules: {
// 对name字段进行必填验证
name: {
// name 字段的校验规则
rules:[
// 校验 name 不能为空
{
required: true,
message: '请填写姓名',
},
// 对name字段进行长度验证
{
minLength: 3,
maxLength: 5,
message: '{label}长度在 {minLength} 到 {maxLength} 个字符',
}
],
label:'姓名'
}
}
rules 属性说明
每一个验证规则中,可以配置多个属性,下面是一些常见规则属性。实际上这里的规范,与uniCloud的DB Schema规范相同。
属性名 | 类型 | 默认值 | 可选值 | 说明 |
---|---|---|---|---|
required | Boolean | - | 是否必填,配置此参数不会显示输入框左边的必填星号,如需要,请配置uni-forms-item 组件的的required为true |
|
range | Array | - | - | 数组至少要有一个元素,且数组内的每一个元素都是唯一的。 |
format | String | - | - | 内置校验规则,如这些规则无法满足需求,可以使用正则匹配或者自定义规则 |
pattern | RegExp | - | - | 正则表达式,如验证邮箱:/^\S+?@\S+?.\S+?$/ (注意不带引号),或使用 "^\S+?@\S+?\.\S+?$"(注意带引号需要使用 \ 转义) |
maximum | Number | - | - | 校验最大值(大于) |
minimum | Number | - | - | 校验最小值(小于) |
maxLength | Number | - | - | 校验数据最大长度 |
errorMessage | String | - | - | 校验失败提示信息语,可添加属性占位符,当前表格内属性都可用作占位符 |
trigger | String | blur | blur/change/submit | 校验触发时机 |
validateFunction | Function | - | - | 自定义校验规则 |
format属性值说明
属性名 | 说明 |
---|---|
string | 必须是 string 类型,默认类型 |
number | 必须是 number 类型 |
boolean | 必须是 boolean 类型 |
array | 必须是 array 类型 |
object | 必须是 object 类型 |
url | 必须是 url 类型 |
必须是 email 类型 |
validateFunction 自定义校验规则使用说明
uni-forms
的 rules
基础规则有时候不能满足项目的所有使用场景,这时候可以使用 validateFunction
来自定义校验规则
validateFunction
方法返回四个参数 validateFunction:function(rule,value,data,callback){}
,当然返回参数名开发者可以自定义:
- rule : 当前校验字段在 rules 中所对应的校验规则
- value : 当前校验字段的值
- data : 所有校验字段的字段和值的对象
- callback : 校验完成时的回调,一般无需执行callback,返回true(校验通过)或者false(校验失败)即可 ,如果需要显示不同的
errMessage
,如果校验不通过需要执行 callback('提示错误信息'),如果校验通过,执行callback()即可
需要注意的是,如果需要使用 validateFunction
自定义校验规则,则不能采用 uni-forms
的 rules
属性来配置校验规则,这时候需要通过ref
,在onReady
生命周期调用组件的setRules
方法绑定验证规则
无法通过props传递变量,是因为微信小程序会过滤掉对象中的方法,导致自定义验证规则无效。
<template>
<view>
<uni-forms ref="form">
<uni-forms-item name="hobby" label="兴趣爱好">
<checkbox-group @change="binddata('hobby',$event.detail.value)">
<label class="label-box">
<checkbox class="transform-scale" value="0" /><text>足球</text>
</label>
<label class="label-box">
<checkbox class="transform-scale" value="1" /><text>篮球</text>
</label>
<label class="label-box">
<checkbox class="transform-scale" value="1" /><text>游泳</text>
</label>
</checkbox-group>
</uni-forms-item>
<button class="button" @click="submit">校验表单</button>
</uni-forms>
</view>
</template>
export default {
data() {
return {
rules: {
hobby: {
rules: [{
required: true,
errorMessage: '请选择兴趣',
},{
validateFunction:function(rule,value,data,callback){
if (value.length < 2) {
callback('请至少勾选两个兴趣爱好')
}
return true
}
}]
}
}
}
},
onReady() {
// 需要在onReady中设置规则
this.$refs.form.setRules(this.rules)
},
methods: {
submit(form) {
this.$refs.form.submit().then(res=>{
console.log('表单数据信息:', res);
}).catch(err =>{
console.log('表单错误信息:', err);
})
}
}
}
validateFunction 异步校验
上面的自定义校验方式为同步校验 ,如果需要异步校验,validateFunction
需要返回一个 Promise
,校验不通过 执行 reject(new Error('错误信息'))
返回对应的错误信息,如果校验通过则直接执行 resolve()
即可,在异步校验方法中,不需要使用 callback
<template>
<view>
<uni-forms :value="formData" ref="form">
<uni-forms-item name="age" label="年龄">
<uni-easyinput v-model="formData.age" type="text" placeholder="请输入年龄" />
</uni-forms-item>
<button class="button" @click="submit">校验表单</button>
</uni-forms>
</view>
</template>
export default {
data() {
return {
rules: {
age: {
rules: [{
required: true,
errorMessage: '请输入年龄',
},{
validateFunction: (rule, value, data, callback) => {
// 异步需要返回 Promise 对象
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value > 10 ) {
// 通过返回 resolve
resolve()
} else {
// 不通过返回 reject(new Error('错误信息'))
reject(new Error('年龄必须大于十岁'))
}
}, 2000)
})
}
}]
}
}
}
},
onReady() {
// 需要在onReady中设置规则
this.$refs.form.setRules(this.rules)
},
methods: {
/**
* 表单提交
* @param {Object} event
*/
submit() {
uni.showLoading()
this.$refs.form.submit().then(res => {
uni.hideLoading()
console.log('表单数据信息:', res);
}).catch(err => {
uni.hideLoading()
console.log('表单错误信息:', err);
})
}
}
}
表单校验时机说明
不管是在规则里还是uni-forms
、uni-forms-item
里,都有 validateTrigger
属性, validateTrigger
属性规定了表单校验时机,当前只有 bind
、submit
两个值域
bind
: 数据绑定时触发校验,uni-esayinput
、uni-data-checkbox
组件表现为数据发生变化时。其他内置或三方组件为binddata
事件执行时机
<template>
<view>
<uni-forms ref="form" :value="formData" validate-trigger="bind">
<uni-forms-item name="age" label="年龄">
<!-- uni-easyinput 的校验时机是数据发生变化, 即触发 input 时 -->
<uni-easyinput v-model="formData.age" type="text" placeholder="请输入年龄" />
</uni-forms-item>
<uni-forms-item name="email" label="邮箱">
<!-- input 的校验时机是触发 binddata 时, 即触发 blur 时 -->
<input v-model="formData.email" @blur="binddata('email',$event.detail.value)" />
</uni-forms-item>
<button class="button" @click="submit">校验表单</button>
</uni-forms>
</view>
</template>
submit
: 只有提交表单才会触发表单校验
对于表单校验时机,同时只会有一个 validateTrigger
发生作用,它的作用权重为
规则 > uni-forms-item > uni-forms
- 如果规则里配置
validateTrigger
,则优先使用规则里的validateTrigger
属性来决定表单校验时机 - 如果规则里没有配置
validateTrigger
,则优先使用uni-forms-item
的validateTrigger
属性来决定表单校验时机 - 如果
uni-forms-item
组件里没有配置validateTrigger
,则优先使用uni-forms
的validateTrigger
属性来决定表单校验时机 - 以此类推,如果都没有使用
validateTrigger
属性,则会使用uni-forms
的validateTrigger
属性默认值来决定表单校验时机
API
Forms Props
属性名 | 类型 | 默认值 | 可选值 | 说明 |
---|---|---|---|---|
v-model/value | Object | - | - | 表单数据 |
rules | Object | - | - | 表单校验规则 |
validate-trigger | String | submit | bind/submit | 表单校验时机 |
label-position | String | left | top/left | label 位置 |
label-width | String/Number | 75 | - | label 宽度,单位 px |
label-align | String | left | left/center/right | label 居中方式 |
err-show-type | String | undertext | undertext/toast/modal | 表单错误信息提示方式 |
border | Boolean | false | - | 是否显示分格线 |
Forms Events
事件称名 | 说明 |
---|---|
validate | 任意表单项被校验后触发,返回表单校验信息 |
Forms Methods
方法称名 | 说明 |
---|---|
submit | 对整个表单进行校验的方法,会返回一个 promise |
setValue | 设置表单某一项 name 的对应值,通常在 uni-forms-item 和自定表单组件中使用 |
validateField | 部分表单进行校验 |
clearValidate | 移除表单的校验结果 |
resetFields | 重置表单 |
/**
* 模板 <uni-forms ref="form"></uni-forms>
*/
// 对整个表单进行校验,返回一个 Promise
this.$refs.form.submit().then((res)=>{
// 成功返回,res 为表单数据
// 其他逻辑处理
// ...
}).catch((err)=>{
// 表单校验验失败,err 为具体错误信息
// 其他逻辑处理
// ...
})
// 设置表单某项对应得值来触发表单校验
// 接受两个参数,第一个参数为表单域的 name ,第二个参数为表单域的值
this.$refs.form.setValue('name','内容')
// 部分表单进行校验,接受一个参数,类型为 String 或 Array ,只校验传入 name 表单域的值
this.$refs.form.validateField(['name', 'email']).then((res)=>{
// 成功返回,res 为对应表单数据
// 其他逻辑处理
// ...
}).catch((err)=>{
// 表单校验验失败,err 为具体错误信息
// 其他逻辑处理
// ...
})
// 移除表单校验,接受一个参数,类型为 String 或 Array ,只移除传入 name 表单域的值,如果不传入参数,则移除所有
this.$refs.form.clearValidate(['name', 'email'])
FormsItem Props
属性名 | 类型 | 默认值 | 可选值 | 说明 |
---|---|---|---|---|
name | String | - | - | 表单域的属性名,在使用校验规则时必填 |
required | Boolean | false | 左边显示红色"*"号,样式显示不会对校验规则产生效果 | |
validate-trigger | String | submit | bind/submit | 表单校验时机 |
left-icon | String | - | - | label左边的图标,限uni-ui的图标名称 |
icon-color | String | #606266 | - | 左边通过icon配置的图标的颜色 |
label | String | - | - | 输入框左边的文字提示 |
label-width | Number | 65 | - | label的宽度,单位px |
label-align | String | left | left/center/right | label的文字对齐方式 |
label-position | String | left | top/left | label的文字的位置 |
error-message | String | - | - | 显示的错误提示内容,如果为空字符串或者false,则不显示错误信息 |