1、表单验证介绍
下面来讲解iviewui表单验证的实现,下面上示例代码:
<template>
<Form ref="formInline" :model="formInline" :rules="ruleInline" inline>
<FormItem prop="user"><!--prop属性不能少-->
<Input type="text" v-model="formInline.user" placeholder="Username">
<Icon type="ios-person-outline" slot="prepend"></Icon>
</Input>
<--formInline.user关联的变量值-->
</FormItem>
<FormItem prop="password">
<Input type="password" v-model="formInline.password" placeholder="Password">
<Icon type="ios-lock-outline" slot="prepend"></Icon>
</Input>
</FormItem>
<FormItem>
<Button type="primary" @click="handleSubmit('formInline')">Signin</Button>
</FormItem>
</Form>
</template>
<script>
export default {
data () {
return {
formInline: {
user: '',
password: ''
},
ruleInline: {
user: [
{ required: true, message: 'Please fill in the user name', trigger: 'blur' }
],
password: [
{ required: true, message: 'Please fill in the password.', trigger: 'blur' },
{ type: 'string', min: 6, message: 'The password length cannot be less than 6 bits', trigger: 'blur' }
]
}
}
},
methods: {
handleSubmit(name) {
this.$refs[name].validate((valid) => {
if (valid) {
this.$Message.success('Success!');
} else {
this.$Message.error('Fail!');
}
})
}
}
}
</script>
错误演示效果如下:
表单项的props
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
prop | 对应表单域 model 里的字段 | String | - |
label | 标签文本 | String | - |
label-width | 表单域标签的的宽度 | Number | - |
label-for | 指定原生的 label 标签的 for 属性,配合控件的 element-id 属性,可以点击 label 时聚焦控件。 | String | - |
required | 是否必填,如不设置,则会根据校验规则自动生成 | Boolean | - |
rules | 表单验证规则 | Object | Array | - |
error | 表单域验证错误信息, 设置该值会使表单验证状态变为error,并显示该错误信息 | String | - |
show-message | 是否显示校验错误信息 | Boolean | true |
表单的props
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
model | 表单数据对象 | Object | - |
rules | 表单验证规则,具体配置查看 async-validator | Object | - |
inline | 是否开启行内表单模式 | Boolean | false |
label-position | 表单域标签的位置,可选值为 left 、right 、top | String | right |
label-width | 表单域标签的宽度,所有的 FormItem 都会继承 Form 组件的 label-width 的值 | Number | - |
show-message | 是否显示校验错误信息 | Boolean | true |
autocomplete | 原生的 autocomplete 属性,可选值为 off 或 on | String | off |
hide-required-mark 4.0.0 | 是否隐藏所有表单项的必选标记 | Boolean | false |
label-colon 4.0.0 | 是否自动在 label 名称后添加冒号 | Boolean | false |
disabled 4.0.0 | 是否禁用该表单内的所有组件(适用于具有 disabled 属性的表单类组件) | Boolean | false |
表单的events
事件名 | 说明 | 返回值 |
---|---|---|
on-validate 4.0.0 | 任一表单项被校验后触发,返回表单项 prop、校验状态、错误消息 | prop, status, error |
表单的methods
方法名 | 说明 | 参数 |
---|---|---|
validate | 对整个表单进行校验,参数为检验完的回调,会返回一个 Boolean 表示成功与失败,支持 Promise | callback |
validateField | 对部分表单字段进行校验的方法,参数1为需校验的 prop,参数2为检验完回调,返回错误信息 | callback |
resetFields | 对整个表单进行重置,将所有字段值重置为空并移除校验结果 | 无 |
表单项的slot
名称 | 说明 |
---|---|
无 | 内容 |
label | label 内容 |
如下代码部分的“ruleInline”就是表单的验证规则,规则属性有哪些:
2、规则属性介绍
2.1 Type = 类型
指示type
要使用的验证器。可识别的类型值为:
string
:必须是string
类型,默认类型number
:必须是number
类型boolean
:必须是boolean
类型method
:必须是function
类型regexp
:必须是的实例RegExp
或创建新的时不会产生异常的字符串RegExp
integer
:必须是number
整数类型float
:必须是number
浮点数类型array
:必须是由数组Array.isArray
object
:必须是object
且不是Array.isArray
enum
:值必须存在于enum中
date
:值必须为Date类型
url
:必须是url
类型hex
:必须是hex
类型email
:必须是email
类型any
:可以是任意类型
2.2 Required
规则属性required
表示该字段必须存在于被验证的源对象上
2.3 Pattern
规则pattern
属性指示值必须匹配才能通过验证的正则表达式
2.4 Range
min
使用和属性定义范围max
。对于string
和array
类型,比较是针对进行的length
,对于number
类型,数字不得小于min
或大于max
。
2.5 Length
要验证字段的精确长度,请指定len
属性。对于string
和array
类型,对属性执行比较length
,对于number
类型,此属性表示与完全匹配number
,即,它可能仅严格等于len
。
如果该len
属性与min
和max
范围属性结合使用,len
则优先。
2.6 Enumerable
要从可能值列表中验证一个值,请使用enum
带有enum
列出该字段有效值的属性的类型,例如:
const descriptor = {
role: { type: 'enum', enum: ['admin', 'user', 'guest'] },
};
2.7 Whitespace
通常将仅包含空格的必填字段视为错误。要对仅由空格组成的字符串添加额外测试,请whitespace
向值为 的规则添加属性true
。规则必须是类型string
。
您可能希望清理用户输入而不是测试空格,请参阅转换以获取允许您去除空格的示例。
2.8 Deep Rules
如果您需要验证深层对象属性,则可以通过将嵌套规则分配给规则的属性来对object
或类型的验证规则进行验证。array
fields
const descriptor = {
address: {
type: 'object',
required: true,
fields: {
street: { type: 'string', required: true },
city: { type: 'string', required: true },
zip: { type: 'string', required: true, len: 8, message: 'invalid zip' },
},
},
name: { type: 'string', required: true },
};
const validator = new Schema(descriptor);
validator.validate({ address: {} }, (errors, fields) => {
// errors for address.street, address.city, address.zip
});
规则示例:
{ name: { type: 'string', required: true, message: 'Name is required' } }
其它规则示例:
export default {
data() {
return {
title: '管理平台',
address: 'title.png',
sendAuthCode: true, /* 布尔值,通过v-show控制显示‘获取按钮'还是‘倒计时' */
auth_time: '120', /* 倒计时 计数器 */
firstForm: {},
thirdForm: {
userName: '',
account: '',
password: '',
email: '',
telephone: '',
fax: '',
postCode: '',
phone: '',
phoneValidation: '',
captchaCode: '',
},
captchaUrl: `${global.CTX}/captcha`,
rules: {
userName: [
{ required: true, message: '请输入管理员姓名', trigger: 'blur' },
{ min: 1, max: 20, message: '管理员姓名在20字以内', trigger: 'blur' },
],
account: [
{ required: true, message: '请输入管理员账号', trigger: 'blur' },
{ min: 1, max: 50, message: '管理员账号在50字以内', trigger: 'blur' },
{ pattern: /^\S+$/, message: '账号不允许有空格', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入长度为10-20位包含数字、字母、特殊字符的密码', trigger: 'blur' },
{ pattern: /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W_]).{10,20}$/, message: '请输入长度为10-20位包含数字、字母、特殊字符的密码', trigger: 'blur' },
],
postCode: [
{ max: 10, message: '邮编长度10位以内', trigger: 'blur' },
],
fax: [
{ max: 50, message: '传真长度50字以内', trigger: 'blur' },
],
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ max: 50, message: '邮箱在50字以内', trigger: 'blur' },
{ pattern: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/, message: '请检查邮箱格式是否正确', trigger: 'blur' },
],
//最后的校验规则,不需要自己写校验规则也可以写成 { type: 'email', message: '请检查邮箱格式是否正确', trigger: 'blur' },
/*type的枚举值有
string: Must be of type string. This is the default type.
number: Must be of type number.
boolean: Must be of type boolean.
method: Must be of type function.
regexp: Must be an instance of RegExp or a string that does not generate an exception when creating a new RegExp.
integer: Must be of type number and an integer.
float: Must be of type number and a floating point number.
array: Must be an array as determined by Array.isArray.
object: Must be of type object and not Array.isArray.
enum: Value must exist in the enum.
date: Value must be valid as determined by Date
url: Must be of type url.
hex: Must be of type hex.
email: Must be of type email.
https://github.com/yiminghe/async-validator#type
https://www.cnblogs.com/chaoxiZ/p/10136780.html
*/
telephone: [
{ max: 50, message: '电话长度在50位以内', trigger: 'blur' },
],
phone: [
{ required: true, message: '请输入手机号码', trigger: 'blur' },
{ pattern: /^((1[3,5,8][0-9])|(14[5,7])|(17[0,5,6,7,8])|(19[7]))\d{8}$/, message: '请检查手机号是否正确', trigger: 'blur' },
],
phoneValidation: [
{ required: true, message: '请输入手机验证码', trigger: 'blur' },
],
captchaCode: [
{ required: true, message: '请输入图片验证码', trigger: 'blur' },
],
},
};
},
components: {
titleBar,
navBar,
},
methods: {
// 是否显示密码
showPwd() {
const input = document.getElementById('pwd');
if (input.type === 'password') {
input.type = 'text';
} else if (input.type === 'text') {
input.type = 'password';
}
},
// 刷新图片验证码
refresh() {
this.captchaUrl = `${global.CTX}/captcha?tm=${Math.random()}`;
},
// 倒计时
getAuthCode() {
if (this.authTimeTimer) {
clearTimeout(this.authTimeTimer);
}
this.authTimeTimer = setTimeout(() => {
this.auth_time -= 1;
if (this.auth_time < 0) {
this.sendAuthCode = true;
clearTimeout(this.authTimeTimer);
} else {
this.getAuthCode();
}
}, 1000);
},
// 发送短信
sendMsg(phoneNum) {
this.$refs.thirdForm.validateField('phone', (phoneError) => {
console.log(`${phoneError}***************************`);
if (!phoneError) {
this.auth_time = 120;
this.sendAuthCode = false;
api.sendMsg({
params: {
params: {
phone: phoneNum,
reason: 'developerReg',
},
},
}).then(() => {
this.getAuthCode();
this.$confirm('验证码已发送至登记手机号上,请查收。', {
confirmButtonText: '确定',
center: true,
});
}).catch((err) => {
this.sendAuthCode = true;
this.$message({
message: err.response.message,
type: 'error',
});
});
}
});
},
// 验证登入账号是否存在
checkDevpUserAccount(account) {
api.checkDevpUserAccount({
params: {
params: {
account,
},
},
}).then((data) => {
if (data.state === 0) {
this.checkCaptcha();
}
}).catch((err) => {
this.$message({
message: err.response.message,
type: 'error',
});
});
},
// 图片验证码验证是否正确
checkCaptcha() {
api.getCaptcha({
params: {
params: {
captchaCode: this.thirdForm.captchaCode,
},
},
}).then(() => {
this.checkSmsValidCode();
}).catch((err) => {
this.$message({
message: err.tip,
type: 'error',
});
this.refresh();
});
},
// 验证短信验证码
checkSmsValidCode() {
api.verifySmsValidCode({
params: {
params: {
phone: this.thirdForm.phone,
reason: 'developerReg',
validCode: this.thirdForm.phoneValidation,
},
},
}).then((data) => {
if (data.state === 0) {
this.submit();
}
}).catch((err) => {
this.$message({
message: err.tip,
type: 'error',
});
});
},
// 上一步
previousStep() {
sessionStorage.setItem('needSecondStepCache', '1');
this.$router.push({ name: 'DeveloperSecond' });
},
// 下一步
nextStep(thirdForm) {
this.$refs[thirdForm].validate((valid) => {
if (valid) {
this.checkDevpUserAccount(this.thirdForm.account);
}
});
},
// 向后台提交数据
submit() {
if (this.firstForm.devpType === '1') {
this.thirdForm.userName = this.firstForm.devpNameself;
}
this.secondForm.cmmiLevel = (this.secondForm.cmmiLevel === '无' ? '' : this.secondForm.cmmiLevel);
this.secondForm.isoLevel = (this.secondForm.isoLevel === '无' ? '' : this.secondForm.isoLevel);
const passwordTemp = md5(this.thirdForm.password);
api.registeredDeveloper({
params: {
data: {
devpType: this.firstForm.devpType,
devpName: this.firstForm.devpName,
devpCode: this.firstForm.devpCode,
logo: this.firstForm.logo,
companyAddress: this.firstForm.companyAddress,
companyDescrible: this.firstForm.companyDescrible,
companyBusiness: this.firstForm.companyBusiness,
identifyPositiveId: this.firstForm.identifyPositiveId,
identifyReverseId: this.firstForm.identifyReverseId,
employeeCode: this.firstForm.employeeCode,
remarks: this.firstForm.remarks,
cmmiLevel: this.secondForm.cmmiLevel,
isoLevel: this.secondForm.isoLevel,
qualificationId: this.secondForm.qualificationId,
userName: this.thirdForm.userName,
account: this.thirdForm.account,
password: passwordTemp,
email: this.thirdForm.email,
telephone: this.thirdForm.telephone,
fax: this.thirdForm.fax,
postCode: this.thirdForm.postCode,
phone: this.thirdForm.phone,
},
},
}).then(() => {
this.$router.push({
name: 'ReturnSuccessMsg',
params: {},
});
}).catch((err) => {
this.$message({
message: err.response.message,
type: 'error',
});
});
},
},
mounted() {
this.firstForm = JSON.parse(sessionStorage.getItem('firstForm')) || {};
this.secondForm = JSON.parse(sessionStorage.getItem('secondForm')) || {};
},
};
</script>