小程序表单校验uni-forms正确使用方式及避坑指南
- 一、前言
- 二、成果展示
- 三、uni-forms即时校验
- 四、uni-forms自定义校验规则
- 五、uni-forms异步校验
- 六、完整示例源码
- 七、最后,点个赞
一、前言
小程序上使用表单理应是很常用,也很必须的功能,因为系统实用了uni-app,所以这时候会用到uni-forms,但使用过程中遇到不少问题。
这边的需求有3个:
- 即时校验(输入框失焦立即校验值)
- 需自定义校验规则
- 需要异步校验
满足这3个需求,就能实现绝大部分表单校验,然而直接使用官方的案例并不能满足,踩过不少坑,最后解决方案如下。
二、成果展示
以下展示均满足上述3个需求,下面示例代码可以直接看 第六点
三、uni-forms即时校验
实现即时校验,uni-forms需要加validate-trigger="bind"
,同时input添加@blur="binddata('字段名', $event.detail.value)"
示例:
<uni-forms ref="form" :modelValue="ruleForm" validate-trigger="bind">
<uni-forms-item label="账号" name="account">
<input v-model.trim="ruleForm.account"
@blur="binddata('account', $event.detail.value)"
placeholder="请输入您的登录账号" />
</uni-forms-item>
</uni-forms>
四、uni-forms自定义校验规则
需要自定义校验规则时,去掉uni-forms的:rules,同时onReady里加this.$refs.form.setRules(this.rules)
,其中validateFunction: this.checkEmail为自定义校验方法
示例:
<template>
<uni-forms ref="form" :modelValue="ruleForm" validate-trigger="bind">
......
</uni-forms>
</template>
<script>
export default {
data() {
return {
// 校验规则
rules: {
email: {
rules: [
{
validateFunction: this.checkEmail,
},
],
},
},
};
},
onReady() {
// 需要在onReady中设置规则
this.$refs.form.setRules(this.rules);
},
methods: {
/**
* 表单验证邮箱
*/
checkEmail(rule, value, allData, callback) {
if (value !== "" && !verifyEmail(value)) {
return callback("邮箱不正确");
}
callback();
},
},
};
</script>
五、uni-forms异步校验
通常使用异步方法来校验账号是否重复等,步骤:
- 首先需要自定义校验方法
validateFunction: this.checkAccount
- 然后进行常规的规则校验
- 再进行异步方法校验账号唯一性
需要使用Promise,校验通过使用return resolve()
校验失败使用return reject(new Error('错误提示信息'))
示例(核心代码部分):
export default {
data() {
return {
// 校验规则
rules: {
account: {
rules: [
{
required: true,
errorMessage: '请输入您的账号',
},
{
validateFunction: this.checkAccount,
},
],
},
},
};
},
methods: {
// 表单验证账号
checkAccount(rule, value) {
return new Promise((resolve, reject) => {
// 先进行规则校验
if (value === '' || !verifyAccount(value)) {
return reject(new Error('只能输入4-30位英文、数字、下划线'))
}
// 再进行异步校验,checkUser为本系统api异步方法,结合你系统使用你自己的方法
apiCheckAccount({ account: value })
.then((data) => {
if (data.exist) {
return reject(new Error('账号已存在'))
}
resolve()
})
.catch((err) => {
return reject(new Error(err.message))
})
})
},
},
六、完整示例源码
<template>
<view class="register">
<view class="title">最实用表单校验</view>
<uni-forms ref="form" :modelValue="ruleForm" validate-trigger="bind" label-width="40">
<uni-forms-item label="账号" name="account">
<input v-model.trim="ruleForm.account" @blur="binddata('account', $event.detail.value)" placeholder="请输入您的登录账号" />
</uni-forms-item>
<uni-forms-item label="姓名" name="name">
<input v-model.trim="ruleForm.name" @blur="binddata('name', $event.detail.value)" placeholder="请输入您的姓名" />
</uni-forms-item>
<uni-forms-item class="form-item-center">
<button type="primary" @click="submit()">注册</button>
</uni-forms-item>
</uni-forms>
</view>
</template>
<script>
import { apiCheckAccount } from '@/api'
import { verifyAccount, verifyName } from '@/utils'
export default {
data() {
return {
// 表单数据
ruleForm: {
account: '', // 账号
name: '', // 姓名
},
rules: {},
}
},
onReady() {
this.setRules()
// 需要在onReady中设置规则
this.$refs.form.setRules(this.rules)
},
methods: {
// 提交表单
submit() {
this.$refs.form
.validate()
.then(() => {
uni.showToast({
title: '注册成功!',
duration: 2000,
icon: 'success',
})
})
.catch((err) => {
console.log('表单校验失败:', err)
})
},
// 设置校验规则
setRules() {
this.rules = {
account: {
rules: [
{
required: true,
errorMessage: '请输入您的账号',
},
{
validateFunction: this.checkAccount,
},
],
},
name: {
rules: [
{
required: true,
errorMessage: '请输入您的姓名',
},
{
validateFunction: this.checkName,
},
],
},
}
},
// 验证账号
checkAccount(rule, value) {
return new Promise((resolve, reject) => {
// 先进行规则校验
if (value === '' || !verifyAccount(value)) {
return reject(new Error('只能输入4-30位英文、数字、下划线'))
}
// 再进行异步校验,checkUser为本系统api异步方法,结合你系统使用你自己的方法
apiCheckAccount({ account: value })
.then((data) => {
if (data.exist) {
return reject(new Error('账号已存在'))
}
resolve()
})
.catch((err) => {
return reject(new Error(err.message))
})
})
},
// 验证姓名
checkName(rule, value, allData, callback) {
if (!verifyName(value)) {
return callback('只能输入1-30位中英文和数字')
}
callback()
},
},
}
</script>
七、最后,点个赞
如果帮到你,点个赞再走嘛 :)