表单提交是很常见的功能,本文基于uniapp+uview2.0实现表单常见属性校验处理,使用到组件有u–form、Form-item,基本使用说明如下:
u–form
此组件一般是用于表单验证使用,每一个表单域由一个u-form-item组成,表单域中可以放置u-input、u-checkbox、u-radio、u-switch等。
在表单组中,通过model参数绑定一个对象,这个对象的属性为各个u-form-item内组件的对应变量。
由于表单验证和绑定表单规则时,需要通过ref操作,故这里需要给form组件声明ref="form1"属性。
关于u-from-item内其他可能包含的诸如input、radio等组件,请见各自组件的相关文档说明。
u-form-item
此组件一般需要搭配Form组件使用,也可以单独搭配Input等组件使用,由于此组件参数较多,这里只对其中参数最简要介绍,其余请见底部的API说明:
prop为传入Form组件的model中的属性字段,如果需要表单验证,此属性是必填的。
labelPosition可以配置左侧"label"的对齐方式,可选为left和top。
borderBottom是否显示表单域的下划线,如果给Input组件配置了边框,可以将此属性设置为false,从而隐藏默认的下划线。
如果想在表单域配置左右的图标或小图片,可以通过leftIcon和rightIcon参数实现。
下面结合简单的demo介绍一下基本使用,现在有一个用户信息表单信息,包含基本的用户昵称、头像、生日、简介信息,现在需要对各字段进行校验。点击提交时都为空时的异常提示信息如下图:
代码内容:
<template> <view> <!-- 注意,如果需要兼容微信小程序,最好通过setRules方法设置rules规则 --> <u--form labelPosition="left" :model="model1" :rules="rules" ref="form1"> <u-form-item label="昵称" prop="userInfo.userName" borderBottom ref="item1"> <u--input v-model="model1.userInfo.userName" border="none"></u--input> </u-form-item> <u-form-item label="头像" prop="userInfo.userImg" borderBottom ref="item1"> <u-avatar :src="https://www.atool.online/article/model1.userInfo.userImg" shape="circle" v-model="model1.userInfo.userImg" @click="chooseTheImg()"></u-avatar> </u-form-item> <u-form-item label="性别" prop="userInfo.gender" borderBottom @click="showGender = true; hideKeyboard()" ref="item1"> <u--input v-model="model1.userInfo.gender" disabled disabledColor="#ffffff" placeholder="请选择性别" border="none"></u--input> <u-icon slot="right" name="arrow-right"></u-icon> </u-form-item> <u-form-item label="生日" prop="userInfo.birthday" borderBottom @click="showBirthday = true; hideKeyboard()" ref="item1"> <u--input v-model="model1.userInfo.birthday" disabled disabledColor="#ffffff" placeholder="请选择生日" border="none"></u--input> <u-icon slot="right" name="arrow-right"></u-icon> </u-form-item> <u-form-item label="简介" prop="userInfo.intro" borderBottom ref="item3"> <u--textarea placeholder="不低于3个字" v-model="model1.userInfo.intro" count></u--textarea> </u-form-item> </u--form> <u-button @click="submit">提交</u-button> <u-action-sheet :show="showGender" :actions="actions" title="请选择性别" description="如果选择保密会报错" @close="showGender = false;genderClose()" @select="genderSelect()"> </u-action-sheet> <u-datetime-picker :show="showBirthday" :value="birthday" mode="date" closeOnClickOverlay @confirm="birthdayConfirm" @cancel="birthdayClose" @close="birthdayClose"></u-datetime-picker> </view> </template> <script> export default { data() { return { showGender: false, // 是否显示性别选择 showBirthday: false, // 是否展示生日选择 model1: { userInfo: { userName: 'uView UI', gender: '', userImg: '/static/logo.png', birthday: '', intro: '', } }, actions: [{ name: '男', }, { name: '女', }, { name: '保密', } ], rules: { 'userInfo.userName': { type: 'string', required: true, message: '请填写昵称', trigger: ['blur', 'change'] }, 'userInfo.gender': { type: 'string', max: 1, required: true, message: '请选择男或女', trigger: ['blur', 'change'] }, 'userInfo.userImg': { type: 'string', required: true, message: '请上传头像', trigger: ['blur', 'change'] }, 'userInfo.birthday': { type: 'string', required: true, message: '请选择生日', trigger: ['change'] }, 'userInfo.intro': { type: 'string', required: true, message: '请填写简介', trigger: ['change'] } }, radio: '', switchVal: false }; }, methods: { // 隐藏键盘 hideKeyboard() { uni.hideKeyboard() }, //选择图片 chooseTheImg() { uni.chooseImage({ count: 1, //图片可选择数量 sizeType: ['original', 'compressed'], //original 原图,compressed 压缩图,默认二者都有 sourceType: ['album', 'camera', '海报图库'], //album 从相册选图,camera 使用相机,默认二者都有。 success: res => { let imgFiles = res.tempFilePaths //图片的本地文件路径列表 console.log('本地地址', imgFiles) this.uploadTheImg(imgFiles) } }) }, //上传图片 uploadTheImg(imgFiles) { uni.uploadFile({ url: `XXXXXX`, //后端用于处理图片并返回图片地址的接口 header: { "Content-Type": "multipart/form-data", // formdata提交格式 }, filePath: imgFiles[0], name: 'uploadfile', // 默认 formData: { // 其他的formdata参数 fileType: '2', uid: '10001', fileContainerName: 'default' }, success: res => { let data = JSON.parse(res.data) //返回的是字符串,需要转成对象格式,打印data如下图 if (data.code == 200) { console.log(data.msg) //图片地址 } }, fail: () => {} }) }, // 显示性别列表并校验性别是否为那女 genderSelect(e) { this.model1.userInfo.gender = e.name this.$refs.form1.validateField('userInfo.gender') // 校验头像是否上传 // this.$refs.form1.validateField('userInfo.userImg') }, // 性别选择关闭,校验是否选择性别 genderClose() { this.$refs.form1.validateField('userInfo.gender') }, // 生日选择关闭时校验生日格式以及是否为空 birthdayConfirm(e) { this.showBirthday = false this.model1.userInfo.birthday = uni.$u.timeFormat(e.value, 'yyyy-mm-dd') this.$refs.form1.validateField('userInfo.birthday') }, // 生日列表关闭时校验是否为空 birthdayClose() { this.showBirthday = false this.$refs.form1.validateField('userInfo.birthday') }, submit() { this.$refs.form1.validate().then(res => { console.log("提交表单信息:" + JSON.stringify(this.model1.userInfo)) // uni.$u.toast('校验通过') // 调用服务端入表接口 }).catch(errors => { console.log("失败信息:" + JSON.stringify(errors)) // uni.$u.toast('校验失败') }) } }, onReady() { //如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则。 this.$refs.form1.setRules(this.rules) } }; </script> <style lang="scss"> </style>
规则说明:
校验规则需要从u--form
组件中指定规则名,此处为rules
,data
属性中rules用于定义表单各个属性的校验内容如下:
trigger{String | Array}:触发校验的方式有2种:
change:字段值发生变化时校验 blur:输入框失去焦点时触发 如果同时监听两种方式,需要写成数组形式:[‘change’,
‘blur’] type{String}
内置校验规则,如这些规则无法满足需求,可以使用正则匹配、或者使用validator自定义方法并结合uView自带验证规则。string:必须是 string 类型,默认类型 number:必须是 number 类型 boolean:必须是 boolean 类型
method:必须是 function 类型 regexp:必须是 regexp
类型,这里的正则,指的是判断字段的内容是否一个正则表达式,而不是用这个正则去匹配字段值 integer:必须是整数类型
float:必须是浮点数类型 array:必须是 array 类型 object:必须是 object 类型 enum:必须出现在 enmu
指定的值中 date:必须是 date 类型 url:必须是 url 类型 hex:必须是 16 进制类型 email:必须是 email
类型 any:任意类型 required
布尔值,是否必填,配置此参数不会显示输入框左边的必填星号,如需要,请配置u-form-item的required为true,注意:如需在swiper标签内显示星号,需要给予swiper-item第一个根节点一定的margin样式pattern 要求此参数值为一个正则表达式,如: /\d+/,不能带引号,如:“/\d+/”,组件会对字段进行正则判断,返回结果。
min 最小值,如果字段类型为字符串和数组,会取字符串长度与数组长度(length)与min比较,如果字段是数值,则直接与min比较。
max 最大值,规则同min参数
len 指定长度,规则同min,优先级高于min和max
enum{Array} 指定的值,配合 type: ‘enum’ 使用
whitespace{Boolean} 如果字段值内容都为空格,默认无法通过required:
true校验,如果要允许通过,需要将此参数设置为truetransform{Function},校验前对值进行转换,函数的参数为当前值,返回值为改变后的值,参数如如下:
value:当前校验字段的值 message 校验不通过时的提示信息
validator{Function}:自定义同步校验函数,参数如下:
rule:当前校验字段在 rules 中所对应的校验规则 value:当前校验字段的值
callback:校验完成时的回调,一般无需执行callback,返回true(校验通过)或者false(校验失败)即可
asyncValidator{Function}:自定义异步校验函数,参数如下:rule:当前校验字段在 rules 中所对应的校验规则 value:当前校验字段的值
callback:校验完成时的回调,执行完异步操作(比如向后端请求数据验证),如果不通过,需要callback(new
Error(‘提示错误信息’)),如果校验通过,执行callback()即可
this.$refs.form1.validateField('userInfo.gender')
用于执行表单字段的校验处理;
this.$refs.form1.validate()
用于执行表单提交时各个字段的校验处理;
补充:
from表单中input与左边的lable距离过大问题处理方式:直接修改u-form-item
中的label-width
即可;另外u-input
中如果想添加边框,可以使用customStyle属性,添加示例:
<u-input placeholder="请输入密码" customStyle="border: 5rpx solid #36373d;border-radius: 20rpx;"></u-input>
附:uview表单校验使用的坑
我们在使用uview的时候有些表单项是不允许用户修改的,对应input绑定的数据是用户点击选择框获得的,所以我们在input上写了disabled属性来禁用输入框,但是禁用之后无法触发表单校验的change以及blur,当表单校验不通过,即使后面我们的数据是通过验证的但是提示消息依然存在,虽然可以通过表单验证,但是造成用户体验不好。后面我在想不使用disabled使用readonly但是发现uniapp不支持这个属性。
photo: [ { // 自定义验证函数,见上说明 validator: (rule, value, callback) => { if (this.form.imgUrl) { return true } if (!this.form.imgUrl) { return false } }, message: '请选择图片', // 触发器可以同时用blur和change trigger: ['blur', 'change'], }, ],
以上校验规则无法触发触发器,只有调用表单校验方法的时候提示才会消失
我的解决思路,不在表单校验上述表单项,在用户点击提交的时候自己写方法判断,要是判断不通过则弹框提示
官方参考链接:https://www.uviewui.com/components/form.html
总结
到此这篇关于uniapp和uview2.0实现表单校验实战的文章就介绍到这了,更多相关uniapp和uview2.0表单校验内容请搜索阿兔在线工具以前的文章或继续浏览下面的相关文章希望大家以后多多支持阿兔在线工具!