Vue.js如何優雅的進行form validation?
1. 所有validation rules是被集中管理,而不是每個文件自己一種,導致驗證規則冗餘。
2. 能夠進行remote validate。3. 不用JQuery。現有的插件vuejs/vue-validator · GitHub只能實現普通驗證,但如何解決1,因為vue-validator沒有把校驗規則給抽象出來,沒辦法,現在只能自己代碼上再抽出一層rules來管理。remote validation只能手寫藉助Jquery ajax來驗證。
這個現在我可以回答了。 我覺得 vue-validator 太冗餘了。所以自己寫了個項目用的插件 va.js,它實現了
集中式的管理 校驗規則 和 報錯模板。
報錯時機可選
校驗正確後的數據,已經打包成對象,可以直接用
允許各個頁面對規則進行覆蓋,對報錯信息進行自定義修改,以及允許ajax獲取數據後,再對規則進行補充
按順序來校驗報錯
我寫了一篇博文來記載 va.js的寫作歷程。
va.js——Vue 表單驗證插件的寫作過程這是模型層,或者說 store 應該做的事。不論視圖層用什麼庫,vue 也好,react 也好,都應該由 store 這一塊負責數據的驗證。通過或者不通過,也由 store 向 form 傳遞。
想想這些情況:
一個輸入在多個地方顯示,都要顯示驗證結果;驗證過程依賴其他欄位;驗證依賴非同步請求;由此可見視圖層並不是驗證表單的適當場所。egoist/vue-final-form
這個問題摸索一年了快,動態表單驗證依然很蛋疼。
大概會
手寫指令和方法,計算屬性validate
async-validator
在vuex那層validate
讓後端來validate
vue-validate用著有些難過……vee-validate http://github.com/logaretm/vee-validate/ 好用
vue表單驗證組件 v-verify-plugin
verify
github:https://github.com/liuyinglong/verify
npm:https://www.npmjs.com/package/vue-verify-plugin
install
npm install vue-verify-plugin
use
- html
&
&
&
&
&
&
&
&
&
- js
import Vue from "vue";
import verify from "vue-verify-plugin";
Vue.use(verify);
export default{
data:function(){
return {
username:"",
pwd:""
}
},
methods:{
submit:function(){
if(this.$verify.check()){
//通過驗證
}
}
},
verify:{
username:[
"required",
{
test:function(val){
if(val.length&<2){
return false;
}
return true;
},
message:"姓名不得小於2位"
}
],
pwd:"required"
},
computed:{
verifyError:function(){
return this.$verify.$errors;
}
}
}
指令說明
v-verify
v-erify 在表單控制項元素上創建數據的驗證規則,他會自動匹配要驗證的值以及驗證的規則。
v-verify 修飾符說明
該指令最後一個修飾符為自定義分組
//自定義teacher分組
v-verify.teacher
//自定義student分組
v-verify.student
//驗證時可分開進行驗證
//驗證student 分組
this.$verify.check("student")
//驗證teacher 分組
this.$verify.check("teacher")
//驗證所有
this.$verify.check();
v-verified
v-verified 錯誤展示,當有錯誤時會展示,沒有錯誤時會加上style:none,默認會展示該數據所有錯誤的第一條
該指令為語法糖(見示例)
&
&
&
&
&
&
.join 展示所有錯誤 用逗號隔開
自定義驗證規則
var myRules={
phone:{
test:/^1[34578]d{9}$/,
message:"電話號碼格式不正確"
},
max6:{
test:function(val){
if(val.length&>6) {
return false
}
return true;
},
message:"最大為6位"
}
}
import Vue from "vue";
import verify from "vue-verify-plugin";
Vue.use(verify,{
rules:myRules
});
自己簡單寫一個,支持非同步,支持任意 Vue Component,不限定於 Form Element。
來自:https://github.com/crossjs/plato/blob/master/src/modules/validator/index.js
看 return 部分即可:
import Vue from "vue"
import * as rules from "./rules"
import promisify from "util/promisify"
export default (context, options = {}) =&> {
// options = { scope: "validator", prefix: "/", ...options }
// 只註冊回調,不註冊數據
return () =&> {
Vue.mixin({
beforeCreate () {
const options = this.$options
const { validator } = options
if (validator) {
// 在入口處定義 $validation
Vue.util.defineReactive(this, "$validation", {
fields: [],
errors: []
})
this.$validator = this
nextTick(this, validator.auto)
} else {
const { parent } = options
if (parent parent.$validation) {
this.$validation = parent.$validation
this.$validator = parent.$validator
nextTick(this, parent.$validator.$options.validator.auto)
}
}
}
})
/**
* $validate
*
* validate vm recursively.
*
* @return {Promise}
*/
Vue.prototype.$validate = function (fromEntry) {
const { validate, $validation = {}, $validator } = this
// 如果此處為校驗入口
if ($validator === this !fromEntry) {
// 頂級往下校驗所有子組件
return Promise.all($validation.fields
.map(field =&> field.$validate(true)))
.then(() =&> $validation)
.catch(() =&> Promise.reject($validation))
} else {
if (!validate) {
return Promise.resolve($validation)
}
return Promise.all(Object.keys(validate).map(key =&> {
return new Promise((resolve, reject) =&> {
const { validator = rules[key], rule, message } = validate[key]
if (validator) {
// reject if falsy
promisify(validator(this.value, rule), true)
.then(resolve)
.catch(() =&> {
reject({
field: this.field || this,
rule,
message
})
})
} else {
__PROD__ || console.warn(`"${key}" is NOT a valid validator`)
resolve()
}
})
})).then(() =&> {
updateErrors($validation.errors, this)
return $validation
}).catch(error =&> {
updateErrors($validation.errors, this, error)
return Promise.reject($validation)
})
}
}
function updateErrors (errors, vm, replacement) {
const field = vm.field || vm
const found = errors.some((error, index) =&> {
if (error.field === field) {
if (replacement) {
errors.splice(index, 1, replacement)
} else {
errors.splice(index, 1)
}
return true
}
return false
})
if (!found replacement) {
errors.push(replacement)
}
return errors
}
function nextTick (vm, auto) {
vm.$nextTick(() =&> {
// 定義了校驗規則
if (vm.validate) {
vm.$validation.fields.push(vm)
// 載入完成自動檢查
if (auto) {
vm.$validate()
}
}
})
}
}
}
我也在找尋用vue構建form+驗證的方法。看到這個問題說下自己的思路吧,目前仍未做,只是思路。
目前用的是bootstrap3里的一個驗證方式,就是結合input標籤里的驗證規則,例如:&
這裡 required 就是必填,pattern就是正則規則,利用正則基本可以完成除了遠程驗證之外所有的驗證,form標籤中有一個類,當頁面ready的時候,搜尋所有表單標籤,檢驗是否有驗證的標籤,如果有,就驗證,都驗證過的時候,把submit的按鈕去除disabled屬性,可以提交給後台,後台一樣可以利用pattern來驗證,這樣驗證規則前後台就統一了。考慮前台驗證的目的,就是為了提升體驗,讓訪客可以一次提交不用失敗後重填,所以前台的驗證我覺得以適度就可以,無需太過複雜。特別說的是,在手機端,就不用js驗證了,上面input里的驗證規則可以直接生效,這些就是瀏覽器自帶的驗證功能。核心就是1. 註冊驗證規則, 或使用內置規則
2. 通過提供的鉤子處理驗證失敗時候的提示
使用方法類似於jquery-validate的驗證
xueyou2000/validate-webpack
發現一個輕量級的驗證器 v-verify 簡單好用
- 輕量、簡單好用
- 文檔詳細https://joinyi.github.io/v-verify/
- 高度可定製化
v-verify-plugin,坑的一筆,誰用誰知道,哎。
網上的例子都是:
export default{
data:function(){
return {
username:"",
pwd:""
}
}
}
假如多嵌套一層呢?反正我沒試成功。坑!!!
export default{
data:function(){
return {
formData:{
username:"",
pwd:""
}
}
}
}
個人前端菜鳥一枚, 現在也做到了vue的表單驗證, 同時公司只有我一個前端, 因此復用了其他css框架的配合, 考慮到validate的復用性, 感覺可以把功能拆分為數據驗證模塊和錯誤信息輸出模塊, 其中數據驗證模塊是高可復用性的, 而錯誤信息提示模塊則需根據項目需求和框架配置進行擴展和更換
試試這個自帶氣泡提示的vue校驗插件,配合vue-hook-form能夠輕鬆實現表單校驗
使用vue-validator插件,裡面有詳細的文檔,基本可以滿足所有需求
vue 可以用雙向綁定和過濾器的方式來實現 keyup 時的一些顯示。如必填。長度限制等信息
驗證的方法可以作用在 submit 上。單獨用函數去處理。
個人認為,用計算屬性基本上能覆蓋 80% 以上的表單驗證場景
我的做法是把表單域封裝成Vue組件,公開validate方法,驗證規則函數validator(正則也可以)作為可選prop傳入。在form需要提交的時候調用每個表單域的validate方法即可。
基本我面試別人都會問validation,因為這個可以涉及到很多東西。用過大量的驗證控制項,自己也寫了一整套。如果只是數據必填,數據格式驗證,都還好。加上remote還可以。還有嵌套驗證,依賴驗證等等,還有調用方式,參數定義,錯誤提醒,要考慮到很多。想著想著還是回去再整整我的代碼吧。說半天沒有說到vue,我覺得從數據層面定義參數我不是很喜歡,控制dom才能做到通用定義。
用jquery validate,用vue去做他該做的事情
推薦閱讀:
※Vue 中如何使用 MutationObserver 做批量處理?
※有什麼UI組件庫可以兼容三大框架,vue,react,angular嗎?
※在react 、 vue 、ng 這些框架火起來之前,是哪些框架比較火?它們現在怎麼樣了?
※Vue、React和Angular 2.x,誰是2016年的主流?