介绍
开发移动端的项目(pc的项目我基本都直接用UI框架的了。。)常会遇到提交表单前,验证表单的需求,如果使用了第三方的UI库这个很好实现,第三方库基本都提供了form验证的api,比如
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="rules"
label-width="120px"
class="demo-ruleForm"
:size="formSize"
status-icon
>
<el-form-item label="Activity name" prop="name">
<el-input v-model="ruleForm.name" />
</el-form-item>
...
<van-form @failed="onFailed">
<van-cell-group inset>
<!-- 通过 pattern 进行正则校验 -->
<van-field
v-model="value1"
name="pattern"
placeholder="正则校验"
:rules="[{ pattern, message: '请输入正确内容' }]"
/>
....
但有时移动端的表单并不那么复杂,而且需要按照公司的设计稿绘制,于是我就写了一个简单的验证表单的方法:
validForm.js
目前支持 required、pattern,你可以在代码里添加校验规则
import { showToast } from './toast'
/**
*
* @param {object} formObj
* @param {Array<any>} rulesArr
* @returns
*/
export default function validForm(formObj = {}, rulesArr = []) {
return new Promise((resolve, reject) => {
for (let i = 0; i < rulesArr.length; i++) {
const keyObj = rulesArr[i]
for (let key in keyObj) {
const keyRules = keyObj[key]
for (let k = 0; k < keyRules.length; k++) {
const keyRule = keyRules[k]
/**
* 这里开始验证
*/
// 必填
if (keyRule.required) {
let isRequired
if (typeof keyRule.required == 'function') {
isRequired = keyRule.required()
} else {
isRequired = true
}
if (isRequired) {
if (!formObj[key]) {
showToast.warning(keyRule.message ?? '请输入' + key)
return reject()
}
}
}
// 正则
if (keyRule.pattern) {
if (!keyRule.pattern.test(formObj[key])) {
showToast.warning(keyRule.message ?? '请输入正确格式的' + key)
return reject()
}
}
/// 这里你可以添加新的规则
}
}
}
return resolve()
})
}
| 参数 | 类型 | 说明 |
|---|---|---|
| 参数1 formObj | object | form的对象 |
| 参数2 rulesArr | Rule[] | 规则数组 |
Rule
| 字段 | 类型 | 说明 |
|---|---|---|
| required | ( boolean | () => boolean ) | 是否必填 |
| pattern | RegExp | 正则表达式 |
| message | string | 规则不符合时的提示语 |
使用
需要设置form和formRules两个变量,<tempalte>中只要 v-model 双向绑定就行,然后提交的时候,调用validForm(form, formRules)
// template中 只需要 v-model 双向绑定就行
<view class="form">
<view class="form_item"><input placeholder="请输入手机号码" v-model="formModel.form.phoneNumber" /></view>
<view class="form_item">
<input placeholder="请输入验证码" v-model="formModel.form.sms" />
</view>
</view>
...
const formModel = reactive({
form: {
phoneNumber: '',
sms: '',
},
})
const formRules = [
{
phoneNumber: [
{ required: true, message: '请输入手机号码' },
{ pattern: patternCreator.mobilePhone.pattern, message: '请输入正确格式的手机号' },
],
},
{ sms: [{ required: true, message: '请输入验证码' }] },
]
...
// 提交
async function submit() {
// 验证
await validForm(formModel.form, formRules) // 验证
...
}
为什么参数2 rulesArr是一个数组
如果rulesArr是一个对象的话,可以减少一次遍历
但是我希望校验的顺序是按照rulesArr的顺序,即先校验 phoneNumber 然后 sms,如果phoneNumber报错就不往下走了。
而如果写成对象,就得用Object.keys,但是Object.keys并不能保证遍历的顺序。