vue3?+?async-validator實現(xiàn)表單驗證的示例代碼
vue3 表單驗證
前言
表單驗證可以有效的過濾不合格的數(shù)據(jù),減少服務器的開銷,并提升用戶的使用體驗。
今天我們使用 vue3 來做一個表單驗證的例子。先來看看完成的效果圖
搭建vue3的項目
創(chuàng)建項目前 這里我們首先要說明的是,我們使用的版本情況
Nodejs:v17.5.0
pnpm:7.0.0
Vue:3.2.25
首先我們 Vite 創(chuàng)建一個 vue3 的項目demo,名字就叫 FormValidate, 我們在命令行輸入命令
pnpm create vite FormValidate
回車
然后選擇 vue
繼續(xù)回車,說明我們已經(jīng)初步創(chuàng)建了 FormValidate (表單驗證)項目
根據(jù)命令行的提示,我們進入項目根目錄,然后使用命令 pnpm install
安裝項目需要的依賴,當然這里使用 pnpm 是比 npm 或者 yarn 快很多的。
接著,我們啟動項目 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.
啟動瀏覽起,輸入地址 http://localhost:3000/
ok, 到這里我們已經(jīng)把項目搭建起來了,結下來我們就開始來說說我們今天主題-表單驗證
vue3的表單驗證
這里我們使用 async-validator 這是個異步驗證表單的插件,在github上有 5k+ 的star,使用的也很廣泛,比如 Ant.design
,Element UI
, Naive UI
等都在使用這個插件,甚至與有些Nodejs后端項目也在使用這個。
先安裝一下這個插件,在命令行輸入
pnpm install async-validator
這里 async-validator
版本是 4.1.1
1.表單代碼
打開項目中的 App.vue 文件,刪除多余的文件內(nèi)容,輸入標題 vue3 表單驗證,并添加一些初始代碼
<template> <div class="main"> <h3>vue3 表單驗證</h3> <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>
是不是看起來有點丑,別急,我們加點css代碼,簡單的美化一下
<template> <div class="main"> <h3>Vue3表單驗證</h3> <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>
2.添加驗證
2-1. 初始化
引入ref
屬性和 async-validator
,這里我們給每個 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ù)表單的情況,我們定義一個對象,這個對象里面存儲了需要校驗的對象和校驗不通過時的信息
const rules = { account: { required: true, message: '請輸入賬號' }, password: { required: true, message: '請輸入密碼' } }
實例化 Schema, 將 rules 傳入 Schema,得到一個 validator
const validator = new Schema(rules)
驗證單個表單我們使用 失去焦點事件, 定義一個函數(shù),將這個函數(shù)添加到 account input上的失焦事件上
// html <input v-model="account" type="text" class="input" @blur="handleBlurAccount" placeholder="請輸入賬號" /> // script const handleBlurAccount = () => {}
接著將實例化后的校驗器函數(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 中測試,我們可以看到在控制臺打印出了 請輸入賬號 等字
同樣的,我們給密碼框也添加如下代碼
//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 } }) }
2-2. 多個表單的驗證
當然這里校驗的只是單個input的,我們接下來說說多個表單的校驗,定義一個點擊事件為submit,將submit事件添加到button上,當然不要忘記阻止瀏覽器默認事件
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方式驗證
了上面的方式,async-validator
還提供 Promise 的方式,我們把 submit 函數(shù)中的代碼修改為如下
validator.validate(form.value).then((value) => { // 校驗通過 console.log(value); }).catch(({ errors, fields }) => { console.log(errors); return errors })
點擊保存,同樣的,我們可以看到控制臺已經(jīng)打印了錯誤信息,說明我們寫的是合適的
2-4. 正則驗證
當然有時候我們會輸入郵箱,電話號碼等表單,這時候我們就需要添加正則來進行驗證了,我們先添加兩個表單,并添加失焦事件, 正則驗證需要用到 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 } }) }
當然,測試是沒有問題的
2-5. 長度控制
假如你要控制表單輸入內(nèi)容的長度,可以使用屬性 min 和 max,我們用 account 這個表單作為例子,我們 rules 對象的 account 中添加這兩個屬性,比如要求賬號最少5個字符,最多10個字符,如下
account: { required: true, min:5, max:10, message: '請輸入賬號' }
我們還可以使用 input 的原生屬性 maxLength="10" 來控制用戶的輸入
2-6. 多個驗證條件
當我們有多個驗證條件的時候,我們可以把 rules 的驗證條件寫成一個數(shù)組,我們還是用 account 這個表單作為例子,比如 賬號要求必須用中文,且賬號最少5個字符,最多10個字符,代碼如下
account: [ { required: true, min:5, max:10, message: '請輸入賬號' }, { required: true, pattern: /[\u4e00-\u9fa5]/, message: '請輸入中文賬號' } ],
2-5. 自定義驗證
有時候,我們會有使用自定義驗證函數(shù)的情況,以滿足特殊驗證情況,這時候,我們可以這樣做
field:{ required: true, validator(rule, value, callback){ return value === ''; }, message: '值不等于 "".', }
到這里,vue3的表單驗證功能雛形已經(jīng)基本出來了,下面我們對驗證功能進行完善
3.優(yōu)化完善
之前的表單驗證雖然已經(jīng)做出了,但是校驗的提示信息是在控制臺,這個很不友好,用戶也看不到提示,所以這里我們完善下這部分功能
首先我們在 label 邊加一個 "*" 表示必填,并且添加樣式,給一個紅色,醒目一些
<label class="label"> <span>賬號</span> <span class="asterisk"> *</span> </label> .asterisk{ color: #d03050; }
我們考慮到 rules
對象中 required
屬性的作用,這里使用 vue 的條件判斷語句 v-if
來判斷,先定義一個函數(shù),名字就叫 getRequired
,然后將 rules.account
,作為參數(shù)傳進去,這里要重點說明一下,如果考慮封裝驗證方法,這里可以不用傳參,不多說,后面講到了,我們再說,先看代碼
<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 }
因為 rules.account
, 有可能是對象或者數(shù)組,這里我們加一個判斷區(qū)別下,如果傳遞進來的是對象,我們直接將屬性required
返回回去,至于required
屬性是否存在,這里沒有必要多判斷。 如果傳遞進來的是數(shù)組,我們使用 some 函數(shù)獲取下結果,然后再返回.
修改 rules.account
的 required
值為false,星號消失,這里只要有一個required
值為true,那么這個星號就顯示
我們接著來添加錯誤信息的顯示與隱藏
我們定義一個對象 modelControl
,這個對象里面動態(tài)存儲錯誤信息,
const modelControl = ref({})
接著給 account
的 input
框添加一個自定義屬性 prop
, 屬性值是 account
, 再加一個div顯示錯誤提示信息
<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; }
為了動態(tài)的顯示和隱藏錯誤信息,我們需要修改失焦事件 和 submit 事件,在事件執(zhí)行的時候,動態(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) => { // 校驗通過 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 })
到這里 表單的動態(tài)驗證功能基本算是完成了,但是我們發(fā)現(xiàn),每次錯誤信息的展示都會使得input框跳動,所以還得調(diào)整下樣式
.form-group { margin: 2px; padding: 10px 15px 3px 0; height:57px; transition: color .3s ease; }
到此這篇關于vue3 + async-validator 實現(xiàn)表單驗證示例代碼的文章就介紹到這了,更多相關vue3表單驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue?button的@click方法無效鉤子函數(shù)沒有執(zhí)行問題
這篇文章主要介紹了vue?button的@click方法無效鉤子函數(shù)沒有執(zhí)行問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03詳解vue3.0 的 Composition API 的一種使用方法
這篇文章主要介紹了vue3.0 的 Composition API 的一種使用方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Vue框架中如何調(diào)用模擬數(shù)據(jù)你知道嗎
這篇文章主要為大家詳細介紹了Vue框架中如何調(diào)用模擬數(shù)據(jù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03Vue中的@blur事件 當元素失去焦點時所觸發(fā)的事件問題
這篇文章主要介紹了Vue中的@blur事件 當元素失去焦點時所觸發(fā)的事件問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08