记录下最近做的两种校验
1. Form 表单的rules校验
2. input输入框的@input校验
1. Form 表单的rule校验
Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将其 form-Item的 prop属性 设置为需校验的字段名即可。
rules内,对form-Item的prop的具体校验规则写在 validator 里,并且通过trigger属性指明校验在何时触发。
<template>
<div class="confirmDialog-wrapper">
<el-dialog
class="confirmDialog"
v-model="visible"
:destroy-on-close="true"
:close-on-click-modal="false"
@close="closeDialog"
>
<template #header>
<span class="title">创建用户</span>
<img src="@/assets/images/warning.svg" />
<span class="grayTips">用户使用手机号登录客户端</span>
</template>
<!-- 表单 -->
<el-form :model="createForm" ref="ruleFormRef" label-width="120px" :rules="rules">
<el-form-item label="用户账号" prop="userAccount">
<el-input
v-model="createForm.userAccount"
placeholder="请输入"
@change="getUserInfo"
maxlength="11"
:disabled="verifyLoading"
/>
<el-icon class="is-spinning" v-if="verifyLoading"><Loading /></el-icon>
<span class="remark">必填,输入手机号,仅限中国大陆手机号码</span>
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="createForm.phone" placeholder="" disabled />
<span class="remark">无需填写,根据用户账号自动带出</span>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input
v-model="createForm.name"
placeholder="请输入"
maxlength="50"
/>
<span class="remark">必填,输入中文、英文或数字</span>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="createForm.email" placeholder="请输入" maxlength="50" />
<span class="remark">必填,输入常用电子邮箱</span>
</el-form-item>
</el-form>
<!-- 取消确认按钮 -->
<template v-slot:footer>
<div class="dialog-footer">
<el-button class="btn-white" @click="closeDialog">取消</el-button>
<el-button
type="primary"
class="btn-blue"
@click="confirm(ruleFormRef)"
:loading="loading"
style="width: auto"
:disabled="verifyLoading"
>确定</el-button
>
</div>
</template>
</el-dialog>
</div>
</template>
//用户表单
let createForm = reactive({
userAccount: '',
phone: '',
name: '',
email: '',
})
/**
* 用户账号校验规则
*/
const validateAccout = (rule, value, callback) => {
// 以1开头,共11位数字
let reg = /^1[3-9]\d{9}$/
if (!value) {
callback(new Error('请输入用户账号'))
} else if (!createForm.phone || !reg.test(value)) {
// 如果没有获取手机号,则提示
callback(new Error('请输入正确的手机号'))
} else {
callback()
}
}
/**
* 用户姓名校验规则
*/
const validateName = (rule, value, callback) => {
// 中文、英文或数字,限制50个字符
let reg = /^[\u4e00-\u9fa5a-zA-Z0-9]{1,50}$/
if (!value) {
callback(new Error('请输入用户姓名'))
} else if (!createForm.name || !reg.test(value)) {
callback(new Error('请输入中文、英文或数字,限制50个字符'))
} else {
callback()
}
}
/**
* 用户邮箱校验规则
*/
const validateEmail = (rule, value, callback) => {
// 常用电子邮箱格式,限制50个字符
let reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
if (!value) {
callback(new Error('请输入邮箱'))
} else if (!createForm.email || !reg.test(value)) {
callback(new Error('请输入常用电子邮箱格式,限制50个字符'))
} else {
callback()
}
}
/**
* 表单校验规则
*/
const rules = reactive({
userAccount: [
{
required: true,
validator: validateAccout,
trigger: 'blur'
}
],
name: [
{
required: true,
validator: validateName,
trigger: 'blur'
}
],
email: [
{
required: true,
validator: validateEmail,
trigger: 'blur'
}
]
})
/**
* 确认按钮回调
*/
function confirm(formEl) {
// 若表单校验不通过,或者验证信息接口正在请求中,则不执行确认操作
if (!formEl || verifyLoading.value) return
// 验证表单每一项
formEl.validate(valid => {
if (valid) {
//创建接口调用
addUserWrap(createForm)
}
})
}
/**
* 创建用户接口
* @param createForm 用户信息
*/
function addUserWrap(createForm) {
loading.value = true
createUser(createForm)
.then(res => {
proxy.$sucTip('创建成功')
closeDialog()
$emit('update')
})
.catch(err => {
proxy.$errorHandle(err)
})
.finally(() => {
loading.value = false
})
}
/**
* 关闭弹框
*/
function closeDialog() {
visible.value = false
//清空表单
ruleFormRef.value.resetFields()
}
/**
* 输入框失去焦点向后端发送请求获取账号信息
*/
function getUserInfo() {
verifyLoading.value = true
if (!createForm.userAccount) {
// 清空表单
createForm.phone = ''
verifyLoading.value = false
return
}
createForm.phone = createForm.userAccount
verifyLoading.value = false
}
2. 通过@input方法校验
测试哥非要改成输入时校验,也就是说,若该输入框应输入中文、英文和数字,则用户输入其他类型字符时,不让用户输得进去。
老实说我觉得这种改法对用户更不友好,但还是想了下怎么做。
贴上示例,基本就是通过@input方法的回调函数,去校验用户在输入框内每次输入的字符。
<el-form-item label="用户账号" prop="userAccount">
<el-input
v-model="createForm.userAccount"
placeholder="请输入"
@change="getUserInfo"
@input="
value => {
createForm.userAccount = noSpecialCode(value, 1)
}
"
maxlength="11"
:disabled="verifyLoading"
/>
<el-icon class="is-spinning" v-if="verifyLoading"><Loading /></el-icon>
<span class="remark">必填,输入手机号,仅限中国大陆手机号码</span>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input
v-model="createForm.name"
placeholder="请输入"
@input="
value => {
createForm.name = noSpecialCode(value, 2)
}
"
maxlength="50"
/>
<span class="remark">必填,输入中文、英文或数字</span>
</el-form-item>
/**
* 输入框输入字符校验
* @value 输入值
* @type 输入框标识 1:账号输入框 2:姓名输入框
*/
function noSpecialCode(value, type) {
let pattern = null
switch (type) {
// 账号输入框校验:非数字
case 1:
pattern = /[\D]*/g
break
// 姓名输入框校验:非中文、非英文、非数字
case 2:
pattern = /[^a-zA-Z\u4e00-\u9fa5\d]/g
break
}
return value.replace(pattern, '')
}
这里的replace方法,就是用pattern这个正则去校验所有的输入value,若正则匹配上,则把该value替换成空字符串' '
2.1. replace方法
replace([RegExp|String],[String|Function])
返回一个新字符串,不改变原字符串本身。接收2个参数
第1个参数可以是字符串,也可以是正则表达式;
同样,第2个参数可以是字符串,也可以是函数。
2.1.1. replace(字符串,字符串)
这种方法有哥问题就是,如果字符串str中有多个待替换的子串,replace()方法只会替换第一个检索到的子串。
如果要把所有待替换的子串都替换掉,就必须多次调用replace方法
let str = '我不喜欢夏雨天,夏雨天很潮湿';
str = str.replace('夏雨','下雨');
console.log(str); // 我不喜欢下雨天,夏雨天很潮湿
2.1.2. replace(正则表达式,字符串)
/夏雨/g是一个正则表达式,使用/ /的正则写法是JavaScript中正则表达式的字面量写法。
正则表达式的末尾有个g,它表示match源字符串str中所有匹配项。
这里如果没有g,那么也只能匹配到第一个子串'夏雨',只有加了g,才能匹配到所有的子串。
let str = '我不喜欢夏雨天,夏雨天很潮湿';
str = str.replace(/夏雨/g,'下雨');
console.log(str); // 我不喜欢下雨天,下雨天很潮湿