最近一直在忙著做項(xiàng)目,在這個(gè)過程中也遇到了很多問題,之前雖然也有做筆記總結(jié),但從未發(fā)過文章,這是第一次嘗試,既為分享,也為記錄,寫得不好請(qǐng)各位多多指正。
言歸正傳,相信大家經(jīng)常都會(huì)遇到要處理表單驗(yàn)證的環(huán)節(jié),而我在最近的項(xiàng)目中也遇到需要做表單驗(yàn)證的業(yè)務(wù),在此做一下小菜鳥的分享。
先上效果圖:
表單校驗(yàn)前的準(zhǔn)備
首先可以先參考Element Plus官網(wǎng)表單組件的校驗(yàn)表單基本格式
地址:Form 表單 | Element Plus
準(zhǔn)備過程總結(jié)為如下三步:
- 從element-plus中引入類型FormInstance和FormRules,并把表單對(duì)象的節(jié)點(diǎn)設(shè)置為FormInstance類型,表單內(nèi)對(duì)所有參數(shù)約束的總規(guī)則(rules)設(shè)置為FormRules類型
- 定義包含表單內(nèi)各參數(shù)的響應(yīng)式數(shù)據(jù)對(duì)象ruleForm,并把ruleForm和rules在表單<el-form>標(biāo)簽的屬性中進(jìn)行單向數(shù)據(jù)綁定。此外需為表單參數(shù)對(duì)應(yīng)的item設(shè)置相應(yīng)的prop和v-model綁定對(duì)應(yīng)ruleForm的參數(shù)
- 定義好提交表單的驗(yàn)證函數(shù),官網(wǎng)例子中為submitForm函數(shù)和resetForm函數(shù)
<template>
<div id="validator-form">
<!-- 以此為例 為表單對(duì)象設(shè)置ref以便后續(xù)獲取該節(jié)點(diǎn)對(duì)象
并為表單對(duì)象添加ruleForm和rules的單向數(shù)據(jù)綁定 此外給姓名參數(shù)的item添加name的prop
以及v-model數(shù)據(jù)雙向綁定ruleForm對(duì)應(yīng)名的參數(shù)-->
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="rules"
label-width="520px"
class="demo-ruleForm"
:size="formSize"
status-icon
>
<el-form-item label="姓名" prop="name">
<el-input v-model="ruleForm.name" placeholder="請(qǐng)輸入名字"/>
</el-form-item>
...
</el-form>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
// 引入類型
import type { FormInstance, FormRules } from "element-plus";
const formSize = ref("default");
// 獲取表單對(duì)象并設(shè)置為FormInstance類型
const ruleFormRef = ref<FormInstance>();
// 定義包含表單內(nèi)各參數(shù)的響應(yīng)式數(shù)據(jù)對(duì)象 用于保存表單參數(shù)
const ruleForm = reactive({
name: "",
sex: "",
height:"",
weight:"",
phone: "",
time: "",
email: "",
birthday:""
});
// 定義包含所有參數(shù)規(guī)則的rules常量并設(shè)置為FormRules類型
const rules = reactive<FormRules>({...})
...
// 表單校驗(yàn)函數(shù)
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
// 校驗(yàn)成功
console.log("submit!");
} else {
// 校驗(yàn)失敗
console.log("error submit!", fields);
}
});
};
//清除校驗(yàn)效果并且清空表單參數(shù)的函數(shù)
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
};
</script>
該案例個(gè)人代碼如下:
<template>
<div id="validator-form">
<!-- 以此為例 為表單對(duì)象設(shè)置ref以便后續(xù)獲取該節(jié)點(diǎn)對(duì)象 -->
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="rules"
label-width="520px"
class="demo-ruleForm"
:size="formSize"
status-icon
>
<el-form-item label="姓名" prop="name">
<el-input v-model="ruleForm.name" placeholder="請(qǐng)輸入名字"/>
</el-form-item>
<el-form-item label="性別" prop="sex">
<el-select v-model="ruleForm.sex" placeholder="請(qǐng)選擇性別">
<el-option label="男" value="male" />
<el-option label="女" value="female" />
</el-select>
</el-form-item>
<el-form-item label="身高(cm)" prop="height">
<el-input v-model.number="ruleForm.height" placeholder="請(qǐng)輸入身高"/>
</el-form-item>
<el-form-item label="體重(kg)" prop="weight">
<el-input v-model="ruleForm.weight" placeholder="請(qǐng)輸入體重"/>
</el-form-item>
<el-form-item label="手機(jī)" prop="phone">
<el-input v-model.number="ruleForm.phone" placeholder="請(qǐng)輸入手機(jī)號(hào)碼"/>
</el-form-item>
<el-form-item label="郵箱" prop="email">
<el-input v-model="ruleForm.email" placeholder="請(qǐng)輸入郵箱"/>
</el-form-item>
<el-form-item label="出生日期" required>
<el-form-item prop="birthday">
<el-date-picker
v-model="ruleForm.birthday"
type="date"
label="Pick a date"
placeholder="請(qǐng)選擇出生日期"
style="width: 100%"
/>
</el-form-item>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)"
>提交</el-button
>
<el-button @click="resetForm(ruleFormRef)">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
// 引入類型
import type { FormInstance, FormRules } from "element-plus";
const formSize = ref("default");
// 獲取表單對(duì)象并設(shè)置為FormInstance類型
const ruleFormRef = ref<FormInstance>();
// 包含表單內(nèi)各參數(shù)的響應(yīng)式數(shù)據(jù)對(duì)象 用于保存表單參數(shù)
const ruleForm = reactive({
name: "",
sex: "",
height:"",
weight:"",
phone: "",
time: "",
email: "",
birthday:""
});
// 定義包含所有參數(shù)規(guī)則的rules常量并設(shè)置為FormRules類型
const rules = reactive<FormRules>({
name: [
{ required: true,type:'string', message: "姓名不能為空", trigger: "blur" },
{ pattern:/[\u4e00-\u9fa5]/,min: 2, max: 15,transform(value){return value.trim()}, message: "姓名格式錯(cuò)誤", trigger: "blur" },
],
sex: [
{ required: true, message: "性別不能為空", trigger: "change" },
],
height: [
{ required: true, message: "身高不能為空", trigger: "blur" },
{ min: 1, max: 300,type:"number", message: "身高范圍為1~300", trigger: "blur" },
],
weight: [
{ required: true, message: "體重不能為空", trigger: "blur" },
{ min: 2, max: 15, message: "體重范圍為1~300", trigger: "blur" },
],
phone: [
{ required: true, message: "手機(jī)不能為空", trigger: "blur" },
{ pattern:/^1[3|4|5|8|9]{1}[0-9]{9}$/,min: 2, max: 15, message: "手機(jī)格式錯(cuò)誤", trigger: "blur" },
],
email: [
{ required: true, message: "郵箱不能為空", trigger: "blur" },
{ pattern:/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,min: 2, max: 15, message: "郵箱格式錯(cuò)誤", trigger: "blur" },
],
birthday: [
{ required: true, message: "出生日期不能為空", trigger: "change" },
],
});
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
console.log("submit!");
} else {
console.log("error submit!", fields);
}
});
};
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
};
</script>
<style lang="less">
#validator-form {
margin-top: 200px;
width: 1500px;
height: 900px;
button{
margin-top: 50px;
}
div{
label{
margin-top: 20px;
}
div{
margin-top: 5px;
}
}
}
</style>
?
?表單校驗(yàn)的重點(diǎn):定義規(guī)則
1.input輸入框原生自帶的type規(guī)則約束
例如type="password",原生自動(dòng)的type類型可以參考這個(gè):<input>:輸入(表單輸入)元素 - HTML(超文本標(biāo)記語言) | MDN
2.根據(jù)不同參數(shù)指定對(duì)應(yīng)的自定義規(guī)則
舉一個(gè)簡單的例子:
const rules = reactive<FormRules>({
name: [
{ required: true,type:'string', message: "姓名不能為空", trigger: "blur" },
{ pattern:/[\u4e00-\u9fa5]/,min: 2, max: 15, message: "姓名格式錯(cuò)誤", trigger: "blur" },
],
// 也可以寫出這種形式 需要定義validatename函數(shù)
//name: [{ validator: validateName, trigger: 'blur' }],
...
})
/*
const validateName = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('Please input the name'))
} else {
if (ruleForm.name !== '') {
if (!ruleFormRef.value) return
ruleFormRef.value.validateField('checkPass', () => null)
}
callback()
}
} */
required:是否為必填項(xiàng),如不設(shè)置,則會(huì)根據(jù)校驗(yàn)規(guī)則確認(rèn)。
type的類型與原生input的type類型不同,它限制對(duì)應(yīng)參數(shù)的類型,其可選項(xiàng)有如下:
string | 必須是類型string
|
number | ?必須是類型number
|
boolean | 必須是類型boolean
|
method | 必須是類型function
|
regexp | 必須是RegExp 創(chuàng)建新的時(shí)不產(chǎn)生異常的實(shí)例或字符串RegExp
|
integer | 必須是類型number 和整數(shù) |
float | 必須是類型number 和浮點(diǎn)數(shù) |
array | 必須是由 確定的數(shù)組Array.isArray
|
object | 必須是 typeobject 而不是Array.isArray
|
enum | 值必須存在于enum
|
date | 值必須是有效的Date
|
url | 必須是類型url
|
hex | 必須是類型hex
|
必須是類型email
|
|
any | 可以是任何類型 |
但是僅僅靠type的限制是遠(yuǎn)遠(yuǎn)無法滿足業(yè)務(wù)需求的,因此
pattern的存在就顯得尤為重要,它代表著rule 屬性指示值必須匹配才能通過驗(yàn)證的正則表達(dá)式。
通過正則表達(dá)式我們可以實(shí)現(xiàn)對(duì)手機(jī)號(hào)碼、郵箱等各項(xiàng)數(shù)據(jù)的合法性進(jìn)行最基本的正確性校驗(yàn)。
3.幾個(gè)小小的注意點(diǎn)
-
要驗(yàn)證字段的確切長度,請(qǐng)指定len屬性。如果該
len
屬性與min
和max
范圍屬性結(jié)合使用,len
則優(yōu)先。 -
使用min和max屬性定義范圍時(shí),對(duì)于string和array類型是針對(duì)其length, 對(duì)應(yīng)number類型則要求它的值不能小于min或大于max
-
此外如果需要驗(yàn)證深層對(duì)象屬性,還可以通過將嵌套規(guī)則分配給規(guī)則的屬性來驗(yàn)證屬于
object
或類型的規(guī)則。
另一種的表單驗(yàn)證:async-validator
其基本用法是:定義描述符,將其分配給模式并將要驗(yàn)證的對(duì)象和回調(diào)函數(shù)傳遞給validate
模式。
與上述的方法在規(guī)則限定上大體相識(shí),使用前記得先install async-validator,其他啥也別說,先上例子:
import Schema from 'async-validator';
const descriptor = {
name: {
type: 'string',
required: true,
validator: (rule, value) => value === 'muji',
},
age: {
type: 'number',
asyncValidator: (rule, value) => {
return new Promise((resolve, reject) => {
if (value < 18) {
reject('too young'); // reject with error message
} else {
resolve();
}
});
},
},
};
const validator = new Schema(descriptor);
validator.validate({ name: 'muji' }, (errors, fields) => {
if (errors) {
// validation failed, errors is an array of all errors
// fields is an object keyed by field name with an array of
// errors per field
return handleErrors(errors, fields);
}
// validation passed
});
// PROMISE USAGE
validator.validate({ name: 'muji', age: 16 }).then(() => {
// validation passed or without error message
}).catch(({ errors, fields }) => {
return handleErrors(errors, fields);
除了可以像常規(guī)方法以對(duì)象的形式那般使用type、pattern正則表達(dá)式限制,它還可以以函數(shù)的形式使用,代碼如下:
import Schema from 'async-validator';
const descriptor = {
name(rule, value, callback, source, options) {
const errors = [];
if (!/^[a-z0-9]+$/.test(value)) {
errors.push(new Error(
util.format('%s must be lowercase alphanumeric characters', rule.field),
));
}
return errors;
},
};
const validator = new Schema(descriptor);
validator.validate({ name: 'Firstname' }, (errors, fields) => {
if (errors) {
return handleErrors(errors, fields);
}
// validation passed
});
如果業(yè)務(wù)十分復(fù)雜,有多重驗(yàn)證的話,使用這個(gè)方法會(huì)更合適,通過官方文檔給出的example可以清晰看到該方法可以使規(guī)則成為對(duì)象數(shù)組,代碼如下:
const descriptor = {
email: [
{ type: 'string', required: true, pattern: Schema.pattern.email },
{
validator(rule, value, callback, source, options) {
const errors = [];
// test if email address already exists in a database
// and add a validation error to the errors array if it does
return errors;
},
},
],
};
官方文檔地址:GitHub - yiminghe/async-validator: validate form asynchronous
個(gè)人總結(jié):
本次項(xiàng)目中做表單驗(yàn)證的過程,我發(fā)現(xiàn)官方文檔永遠(yuǎn)是咋們最可靠的幫手,看懂官方文檔真的基本可以解決遇到的絕大部分問題。文章來源:http://www.zghlxwxcb.cn/news/detail-592475.html
最后,奉上我最近比較喜歡的一句話,從不勝利的人很少失敗,從不攀登的人很少跌倒。希望大家都不畏失敗,不怕跌倒。文章來源地址http://www.zghlxwxcb.cn/news/detail-592475.html
到了這里,關(guān)于在Vue框架項(xiàng)目里通過Element Plus實(shí)現(xiàn)表單驗(yàn)證的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!