vue3?+?async-validator實(shí)現(xiàn)表單驗(yàn)證的示例代碼
vue3 表單驗(yàn)證
前言
表單驗(yàn)證可以有效的過濾不合格的數(shù)據(jù),減少服務(wù)器的開銷,并提升用戶的使用體驗(yàn)。
今天我們使用 vue3 來做一個(gè)表單驗(yàn)證的例子。先來看看完成的效果圖
搭建vue3的項(xiàng)目
創(chuàng)建項(xiàng)目前 這里我們首先要說明的是,我們使用的版本情況
Nodejs:v17.5.0
pnpm:7.0.0
Vue:3.2.25
首先我們 Vite 創(chuàng)建一個(gè) vue3 的項(xiàng)目demo,名字就叫 FormValidate, 我們?cè)诿钚休斎朊?/p>
pnpm create vite FormValidate
回車
然后選擇 vue
繼續(xù)回車,說明我們已經(jīng)初步創(chuàng)建了 FormValidate (表單驗(yàn)證)項(xiàng)目
根據(jù)命令行的提示,我們進(jìn)入項(xiàng)目根目錄,然后使用命令 pnpm install
安裝項(xiàng)目需要的依賴,當(dāng)然這里使用 pnpm 是比 npm 或者 yarn 快很多的。
接著,我們啟動(dòng)項(xiàng)目 pnpm run dev
, 終端中輸出如圖內(nèi)容
vite v2.9.7 dev server running at: > Local: http://localhost:3000/ > Network: use `--host` to expose ready in 954ms.
啟動(dòng)瀏覽起,輸入地址 http://localhost:3000/
ok, 到這里我們已經(jīng)把項(xiàng)目搭建起來了,結(jié)下來我們就開始來說說我們今天主題-表單驗(yàn)證
vue3的表單驗(yàn)證
這里我們使用 async-validator 這是個(gè)異步驗(yàn)證表單的插件,在github上有 5k+ 的star,使用的也很廣泛,比如 Ant.design
,Element UI
, Naive UI
等都在使用這個(gè)插件,甚至與有些Nodejs后端項(xiàng)目也在使用這個(gè)。
先安裝一下這個(gè)插件,在命令行輸入
pnpm install async-validator
這里 async-validator
版本是 4.1.1
1.表單代碼
打開項(xiàng)目中的 App.vue 文件,刪除多余的文件內(nèi)容,輸入標(biāo)題 vue3 表單驗(yàn)證,并添加一些初始代碼
<template> <div class="main"> <h3>vue3 表單驗(yàn)證</h3> <form> <div> <label class="label">賬號(hào)</label> <input type="text" placeholder="請(qǐng)輸入賬號(hào)" class="input" /> </div> <div> <label class="label">密碼</label> <input tyep="password" type="text" class="input" placeholder="請(qǐng)輸入密碼" /> </div> <div> <button>保存</button> </div> </form> </div> </template> <script setup> </script> <style lang="css"> .main{ text-align:center; } .label { padding-right: 10px; padding-left: 10px; display: inline-block; box-sizing: border-box; width: 100px; text-align: right; } .input { width: 200px; height: 30px; margin-top:10px; } </style>
是不是看起來有點(diǎn)丑,別急,我們加點(diǎn)css代碼,簡單的美化一下
<template> <div class="main"> <h3>Vue3表單驗(yàn)證</h3> <form class="form-box"> <div class="form-group "> <label class="label">賬號(hào)</label> <input type="text" class="input" placeholder="請(qǐng)輸入賬號(hào)" /> </div> <div class="form-group"> <label class="label">密碼</label> <input tyep="password" type="text" placeholder="請(qǐng)輸入密碼" class="input" /> </div> <div class="form-group"> <button class="btn ">保存</button> </div> </form> </div> </template> <script setup> </script> <style scoped> .main { text-align: center; } .btn{ margin: 0; line-height: 1; padding: 15px; height: 30px; width: 60px; font-size: 14px; border-radius: 4px; color: #fff; background-color: #2080f0; white-space: nowrap; outline: none; position: relative; border: none; display: inline-flex; flex-wrap: nowrap; flex-shrink: 0; align-items: center; justify-content: center; user-select: none; text-align: center; cursor: pointer; text-decoration: none; } .form-box{ width: 500px; max-width: 100%; margin: 0 auto; padding: 10px; } .form-group{ margin: 10px; padding: 10px 15px 10px 0 } .label { padding-right: 10px; padding-left: 10px; display: inline-block; box-sizing: border-box; width: 110px; text-align: right; } .input { width: calc(100% - 120px); height: 28px; } </style>
2.添加驗(yàn)證
2-1. 初始化
引入ref
屬性和 async-validator
,這里我們給每個(gè) input 框添加 v-model
綁定屬性,
// html <input type="text" v-model="form.account" class="input" placeholder="請(qǐng)輸入賬號(hào)" /> <input tyep="password" v-model="form.password" type="text" placeholder="請(qǐng)輸入密碼" class="input" /> // script import { ref } from "vue" import Schema from 'async-validator'; const form = ref({ account: null, password: null, })
根據(jù)表單的情況,我們定義一個(gè)對(duì)象,這個(gè)對(duì)象里面存儲(chǔ)了需要校驗(yàn)的對(duì)象和校驗(yàn)不通過時(shí)的信息
const rules = { account: { required: true, message: '請(qǐng)輸入賬號(hào)' }, password: { required: true, message: '請(qǐng)輸入密碼' } }
實(shí)例化 Schema, 將 rules 傳入 Schema,得到一個(gè) validator
const validator = new Schema(rules)
驗(yàn)證單個(gè)表單我們使用 失去焦點(diǎn)事件, 定義一個(gè)函數(shù),將這個(gè)函數(shù)添加到 account input上的失焦事件上
// html <input v-model="account" type="text" class="input" @blur="handleBlurAccount" placeholder="請(qǐng)輸入賬號(hào)" /> // script const handleBlurAccount = () => {}
接著將實(shí)例化后的校驗(yàn)器函數(shù)寫到 handleBlurAccount 中
const handleBlurAccount = () => { validator.validate({account: form.value.account}, (errors, fields) => { if (errors && fields.account) { console.log(fields.account[0].message); return errors } }) }
在account 的 input 中測試,我們可以看到在控制臺(tái)打印出了 請(qǐng)輸入賬號(hào) 等字
同樣的,我們給密碼框也添加如下代碼
//html <input v-model="form.password" tyep="password" type="text" @blur="handleBlurPassword" placeholder="請(qǐng)輸入密碼" class="input" /> //script const handleBlurPassword = () => { validator.validate({password: form.value.password}, (errors, fields) => { if (errors && fields.password) { console.log(errors, fields); console.log(fields.password[0].message); return errors } }) }
2-2. 多個(gè)表單的驗(yàn)證
當(dāng)然這里校驗(yàn)的只是單個(gè)input的,我們接下來說說多個(gè)表單的校驗(yàn),定義一個(gè)點(diǎn)擊事件為submit,將submit事件添加到button上,當(dāng)然不要忘記阻止瀏覽器默認(rèn)事件
const submit = (e) => { e.preventDefault(); validator.validate(form.value, (errors, fields) => { if (errors) { for(let key of errors) { console.log(key.message); } return errors } }) }
2-3. Promise方式驗(yàn)證
了上面的方式,async-validator
還提供 Promise 的方式,我們把 submit 函數(shù)中的代碼修改為如下
validator.validate(form.value).then((value) => { // 校驗(yàn)通過 console.log(value); }).catch(({ errors, fields }) => { console.log(errors); return errors })
點(diǎn)擊保存,同樣的,我們可以看到控制臺(tái)已經(jīng)打印了錯(cuò)誤信息,說明我們寫的是合適的
2-4. 正則驗(yàn)證
當(dāng)然有時(shí)候我們會(huì)輸入郵箱,電話號(hào)碼等表單,這時(shí)候我們就需要添加正則來進(jìn)行驗(yàn)證了,我們先添加兩個(gè)表單,并添加失焦事件, 正則驗(yàn)證需要用到 async-validator
的屬性 pattern,我們將符合要求的正則添加到 rules ,代碼如下所示
<div class="form-group "> <label class="label">電話號(hào)碼</label> <input v-model="form.phone" type="text" class="input" @blur="handleBlurPhone" placeholder="請(qǐng)輸入電話號(hào)碼" /> </div> <div class="form-group "> <label class="label">郵箱</label> <input v-model="form.email" type="text" class="input" @blur="handleBlurEmail" placeholder="請(qǐng)輸入郵箱" /> </div> const form = ref({ account: null, email: null, password: null, }) const rules = { account: { required: true, message: '請(qǐng)輸入賬號(hào)' }, phone: { required: true, pattern: /^1\d{10}$/, message: "請(qǐng)輸入電話號(hào)碼" }, email: { required: true, pattern: /^([a-zA-Z0-9]+[_|_|\-|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,6}$/, message: "請(qǐng)輸入郵箱" }, password: { required: true, message: '請(qǐng)輸入密碼' } } const handleBlurPhone = () => { validator.validate({ phone: form.value.phone }, (errors, fields) => { if (errors && fields.phone) { console.log(errors, fields); console.log(fields.phone[0].message); return errors } }) } const handleBlurEmail = () => { validator.validate({ email: form.value.email }, (errors, fields) => { if (errors && fields.email) { console.log(errors, fields); console.log(fields.email[0].message); return errors } }) }
當(dāng)然,測試是沒有問題的
2-5. 長度控制
假如你要控制表單輸入內(nèi)容的長度,可以使用屬性 min 和 max,我們用 account 這個(gè)表單作為例子,我們 rules 對(duì)象的 account 中添加這兩個(gè)屬性,比如要求賬號(hào)最少5個(gè)字符,最多10個(gè)字符,如下
account: { required: true, min:5, max:10, message: '請(qǐng)輸入賬號(hào)' }
我們還可以使用 input 的原生屬性 maxLength="10" 來控制用戶的輸入
2-6. 多個(gè)驗(yàn)證條件
當(dāng)我們有多個(gè)驗(yàn)證條件的時(shí)候,我們可以把 rules 的驗(yàn)證條件寫成一個(gè)數(shù)組,我們還是用 account 這個(gè)表單作為例子,比如 賬號(hào)要求必須用中文,且賬號(hào)最少5個(gè)字符,最多10個(gè)字符,代碼如下
account: [ { required: true, min:5, max:10, message: '請(qǐng)輸入賬號(hào)' }, { required: true, pattern: /[\u4e00-\u9fa5]/, message: '請(qǐng)輸入中文賬號(hào)' } ],
2-5. 自定義驗(yàn)證
有時(shí)候,我們會(huì)有使用自定義驗(yàn)證函數(shù)的情況,以滿足特殊驗(yàn)證情況,這時(shí)候,我們可以這樣做
field:{ required: true, validator(rule, value, callback){ return value === ''; }, message: '值不等于 "".', }
到這里,vue3的表單驗(yàn)證功能雛形已經(jīng)基本出來了,下面我們對(duì)驗(yàn)證功能進(jìn)行完善
3.優(yōu)化完善
之前的表單驗(yàn)證雖然已經(jīng)做出了,但是校驗(yàn)的提示信息是在控制臺(tái),這個(gè)很不友好,用戶也看不到提示,所以這里我們完善下這部分功能
首先我們?cè)?label 邊加一個(gè) "*" 表示必填,并且添加樣式,給一個(gè)紅色,醒目一些
<label class="label"> <span>賬號(hào)</span> <span class="asterisk"> *</span> </label> .asterisk{ color: #d03050; }
我們考慮到 rules
對(duì)象中 required
屬性的作用,這里使用 vue 的條件判斷語句 v-if
來判斷,先定義一個(gè)函數(shù),名字就叫 getRequired
,然后將 rules.account
,作為參數(shù)傳進(jìn)去,這里要重點(diǎn)說明一下,如果考慮封裝驗(yàn)證方法,這里可以不用傳參,不多說,后面講到了,我們?cè)僬f,先看代碼
<span class="asterisk" v-if="getRequired(rules.account)"> *</span> const getRequired = (condition) => { if(Object.prototype.toString.call(condition) === "[object Object]") { return condition.required } else if (Object.prototype.toString.call(condition) === "[object Array]") { let result = condition.some(item => item.required) return result } return false }
因?yàn)?rules.account
, 有可能是對(duì)象或者數(shù)組,這里我們加一個(gè)判斷區(qū)別下,如果傳遞進(jìn)來的是對(duì)象,我們直接將屬性required
返回回去,至于required
屬性是否存在,這里沒有必要多判斷。 如果傳遞進(jìn)來的是數(shù)組,我們使用 some 函數(shù)獲取下結(jié)果,然后再返回.
修改 rules.account
的 required
值為false,星號(hào)消失,這里只要有一個(gè)required
值為true,那么這個(gè)星號(hào)就顯示
我們接著來添加錯(cuò)誤信息的顯示與隱藏
我們定義一個(gè)對(duì)象 modelControl
,這個(gè)對(duì)象里面動(dòng)態(tài)存儲(chǔ)錯(cuò)誤信息,
const modelControl = ref({})
接著給 account
的 input
框添加一個(gè)自定義屬性 prop
, 屬性值是 account
, 再加一個(gè)div顯示錯(cuò)誤提示信息
<div class="form-group"> <label class="label"> <span>賬號(hào)</span> <span class="asterisk" v-if="getRequired(rules.account)"> *</span> </label> <input v-model="form.account" type="text" maxLength="10" class="input" prop="account" @blur="handleBlurAccount" placeholder="請(qǐng)輸入賬號(hào)" /> <div class="input feedback" v-if="modelControl['account']">{{modelControl['account']}}</div> </div> .feedback{ color: #d03050; font-size:14px; margin-top: 3px; text-align:left; margin-left:110px; }
為了動(dòng)態(tài)的顯示和隱藏錯(cuò)誤信息,我們需要修改失焦事件 和 submit 事件,在事件執(zhí)行的時(shí)候,動(dòng)態(tài)的將值賦予或清除,代碼如下
const handleBlurAccount = (e) => { const prop = e.target.attributes.prop.value if (!prop) { return false } validator.validate({ account: form.value.account }, (errors, fields) => { if (errors && fields.account) { console.log(errors, fields); console.log(fields.account[0].message); modelControl.value[prop] = fields[prop][0].message return errors } modelControl.value[prop] = null }) } validator.validate(form.value).then((value) => { // 校驗(yàn)通過 console.log(value); }).catch(({ errors, fields }) => { console.log(errors, fields); for(let key in fields) { modelControl.value[key] = fields[key][0].message } console.log(modelControl); return errors })
到這里 表單的動(dòng)態(tài)驗(yàn)證功能基本算是完成了,但是我們發(fā)現(xiàn),每次錯(cuò)誤信息的展示都會(huì)使得input框跳動(dòng),所以還得調(diào)整下樣式
.form-group { margin: 2px; padding: 10px 15px 3px 0; height:57px; transition: color .3s ease; }
到此這篇關(guān)于vue3 + async-validator 實(shí)現(xiàn)表單驗(yàn)證示例代碼的文章就介紹到這了,更多相關(guān)vue3表單驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue?button的@click方法無效鉤子函數(shù)沒有執(zhí)行問題
這篇文章主要介紹了vue?button的@click方法無效鉤子函數(shù)沒有執(zhí)行問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03vue使用el-upload實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了vue使用el-upload實(shí)現(xiàn)文件上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04詳解vue3.0 的 Composition API 的一種使用方法
這篇文章主要介紹了vue3.0 的 Composition API 的一種使用方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10Vue.js 點(diǎn)擊按鈕顯示/隱藏內(nèi)容的實(shí)例代碼
下面小編就為大家分享一篇Vue.js 點(diǎn)擊按鈕顯示/隱藏內(nèi)容的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-02-02Vue框架中如何調(diào)用模擬數(shù)據(jù)你知道嗎
這篇文章主要為大家詳細(xì)介紹了Vue框架中如何調(diào)用模擬數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03Vue中的@blur事件 當(dāng)元素失去焦點(diǎn)時(shí)所觸發(fā)的事件問題
這篇文章主要介紹了Vue中的@blur事件 當(dāng)元素失去焦點(diǎn)時(shí)所觸發(fā)的事件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08