您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“vue3+async-validator如何實(shí)現(xiàn)表單驗(yàn)證”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“vue3+async-validator如何實(shí)現(xiàn)表單驗(yàn)證”吧!
創(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, 我們在命令行輸入命令
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)證
這里我們使用 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
打開項(xiàng)目中的 App.vue 文件,刪除多余的文件內(nèi)容,輸入標(biāo)題 vue3 表單驗(yàn)證,并添加一些初始代碼
<template> <div class="main"> <h4>vue3 表單驗(yàn)證</h4> <form> <div> <label class="label">賬號</label> <input type="text" placeholder="請輸入賬號" class="input" /> </div> <div> <label class="label">密碼</label> <input tyep="password" type="text" class="input" placeholder="請輸入密碼" /> </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"> <h4>Vue3表單驗(yàn)證</h4> <form class="form-box"> <div class="form-group "> <label class="label">賬號</label> <input type="text" class="input" placeholder="請輸入賬號" /> </div> <div class="form-group"> <label class="label">密碼</label> <input tyep="password" type="text" placeholder="請輸入密碼" 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>
引入ref
屬性和 async-validator
,這里我們給每個(gè) input 框添加 v-model
綁定屬性,
// html <input type="text" v-model="form.account" class="input" placeholder="請輸入賬號" /> <input tyep="password" v-model="form.password" type="text" placeholder="請輸入密碼" class="input" /> // script import { ref } from "vue" import Schema from 'async-validator'; const form = ref({ account: null, password: null, })
根據(jù)表單的情況,我們定義一個(gè)對象,這個(gè)對象里面存儲(chǔ)了需要校驗(yàn)的對象和校驗(yàn)不通過時(shí)的信息
const rules = { account: { required: true, message: '請輸入賬號' }, password: { required: true, message: '請輸入密碼' } }
實(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="請輸入賬號" /> // 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)打印出了 請輸入賬號 等字
同樣的,我們給密碼框也添加如下代碼
//html <input v-model="form.password" tyep="password" type="text" @blur="handleBlurPassword" placeholder="請輸入密碼" 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 } }) }
當(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 } }) }
了上面的方式,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ò)誤信息,說明我們寫的是合適的
當(dāng)然有時(shí)候我們會(huì)輸入郵箱,電話號碼等表單,這時(shí)候我們就需要添加正則來進(jìn)行驗(yàn)證了,我們先添加兩個(gè)表單,并添加失焦事件, 正則驗(yàn)證需要用到 async-validator
的屬性 pattern,我們將符合要求的正則添加到 rules ,代碼如下所示
<div class="form-group "> <label class="label">電話號碼</label> <input v-model="form.phone" type="text" class="input" @blur="handleBlurPhone" placeholder="請輸入電話號碼" /> </div> <div class="form-group "> <label class="label">郵箱</label> <input v-model="form.email" type="text" class="input" @blur="handleBlurEmail" placeholder="請輸入郵箱" /> </div> const form = ref({ account: null, email: null, password: null, }) const rules = { account: { required: true, message: '請輸入賬號' }, phone: { required: true, pattern: /^1\d{10}$/, message: "請輸入電話號碼" }, 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: "請輸入郵箱" }, password: { required: true, message: '請輸入密碼' } } 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)然,測試是沒有問題的
假如你要控制表單輸入內(nèi)容的長度,可以使用屬性 min 和 max,我們用 account 這個(gè)表單作為例子,我們 rules 對象的 account 中添加這兩個(gè)屬性,比如要求賬號最少5個(gè)字符,最多10個(gè)字符,如下
account: { required: true, min:5, max:10, message: '請輸入賬號' }
我們還可以使用 input 的原生屬性 maxLength="10" 來控制用戶的輸入
當(dāng)我們有多個(gè)驗(yàn)證條件的時(shí)候,我們可以把 rules 的驗(yàn)證條件寫成一個(gè)數(shù)組,我們還是用 account 這個(gè)表單作為例子,比如 賬號要求必須用中文,且賬號最少5個(gè)字符,最多10個(gè)字符,代碼如下
account: [ { required: true, min:5, max:10, message: '請輸入賬號' }, { required: true, pattern: /[\u4e00-\u9fa5]/, message: '請輸入中文賬號' } ],
有時(shí)候,我們會(huì)有使用自定義驗(yàn)證函數(shù)的情況,以滿足特殊驗(yàn)證情況,這時(shí)候,我們可以這樣做
field:{ required: true, validator(rule, value, callback){ return value === ''; }, message: '值不等于 "".', }
到這里,vue3的表單驗(yàn)證功能雛形已經(jīng)基本出來了,下面我們對驗(yàn)證功能進(jìn)行完善
之前的表單驗(yàn)證雖然已經(jīng)做出了,但是校驗(yàn)的提示信息是在控制臺(tái),這個(gè)很不友好,用戶也看不到提示,所以這里我們完善下這部分功能
首先我們在 label 邊加一個(gè) "*" 表示必填,并且添加樣式,給一個(gè)紅色,醒目一些
<label class="label"> <span>賬號</span> <span class="asterisk"> *</span> </label> .asterisk{ color: #d03050; }
我們考慮到 rules
對象中 required
屬性的作用,這里使用 vue 的條件判斷語句 v-if
來判斷,先定義一個(gè)函數(shù),名字就叫 getRequired
,然后將 rules.account
,作為參數(shù)傳進(jìn)去,這里要重點(diǎn)說明一下,如果考慮封裝驗(yàn)證方法,這里可以不用傳參,不多說,后面講到了,我們再說,先看代碼
<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
, 有可能是對象或者數(shù)組,這里我們加一個(gè)判斷區(qū)別下,如果傳遞進(jìn)來的是對象,我們直接將屬性required
返回回去,至于required
屬性是否存在,這里沒有必要多判斷。 如果傳遞進(jìn)來的是數(shù)組,我們使用 some 函數(shù)獲取下結(jié)果,然后再返回.
修改 rules.account
的 required
值為false,星號消失,這里只要有一個(gè)required
值為true,那么這個(gè)星號就顯示
我們接著來添加錯(cuò)誤信息的顯示與隱藏
我們定義一個(gè)對象 modelControl
,這個(gè)對象里面動(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>賬號</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="請輸入賬號" /> <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; }
到此,相信大家對“vue3+async-validator如何實(shí)現(xiàn)表單驗(yàn)證”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。