在全棧開發系列第三篇的時候有講到使用Vue進行前端驗證。在那一篇博文里,詳細講了如何搭建 vuefluentvalidator.js 的過程,並最終把它從需要(實體和實體驗證器)到 直接使用,很顯然,它很小巧的勝任了工作。(首先聲明,這個vuefluentvalidator.js是我上周末也就是7月15號才開始構思和編寫的,而我最開始的目的是希望它能輕松完成表單的校驗工作,但沒想過許多復雜多變的情況。所以這期間出現了多次更改和修正)。目前我已將它上傳至github,網址為:https://github.com/gxqsd/vuefluentvalidator。如果你有什么更好的建議,我們可以一起修正。
回到正題,上一篇結束時,我們已經能讓他成功跑起來了。但由於上一篇內容過多,所以還沒來得及介紹下如何使用。
首先我們來看一個例子。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script type="text/javascript" src="vue.js"></script> <script src="vuefluentvalidator.js"></script> </head> <body> <div id="box"> <form action="https://www.baidu.com"> <div> <input type="text" v-model="model.name"> <span>{{model.error.name}}</span> </div> <div> <input type="text" v-model="model.age"> <span>{{model.error.age}}</span> </div> <input type="submit" value="提交" @click="submit({ev:$event})"> </form> </div> <script> let vm = new Vue({ el: '#box', data: { validator: new Validator({ model: { name: undefined, age: undefined, address: { home: undefined, phone: undefined } }, rule: function (than) { than.ruleFor("name") .NotEmpty() .WithMessage("名稱必填") .MinimumLength(5) .WithMessage("最短長度為5"); than.ruleFor("age") .NotEmpty() .WithMessage("年齡必須") .Number(0, 100) .WithMessage("必須在0-100歲之間"); } }), }, methods: { submit: function ({ ev }) { if (this.validator.passValidation()) { return; } ev.preventDefault(); this.validator.validation(ev.target); } }, computed: { model: { get: function () { return this.validator.model; } } } }); </script> </body> </html>
在這個html頁面里,我們引入了vue.js 和 vuefluentvalidator.js。
使用vuefluentvalidator 只需要在data 里 new 一個Validator 。Validator 有兩個參數
第一個是要驗證的數據,他可以是一個JSON對象,或者是一個實體對象 ClassName ,實際上我們可以將整個data的數據放入進去。我們傳入進去的數據會被創建在其內部的model中,也就是說我們只需要通過validator.model 就能訪問我們傳進去的數據。
第二個參數則是一個回調函數,他是用來配置驗證規則的函數。
回調函數默認有一個參數,在validator內部調用時會將this傳進來,所以這個參數也就是validator本身。
通過這個回調函數的參數than,我們就可以進行驗證規則的配置。
目前內置了六種驗證規則。他們分別是
public class Person { /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年齡 /// </summary> public int Age { get; set; } /// <summary> /// 性別 /// </summary> public bool Sex { get; set; } /// <summary> /// 地址 /// </summary> public Address Address { get; set; } }
public class Address { public string Home { get; set; } public string Phone { get; set; } }
我們在為Person設置Address的驗證規則時,使用了SetValidator方式。
public class PersonValidator : AbstractValidator<Person> { public PersonValidator() { this.RuleFor(p => p.Name) .NotEmpty() .WithMessage("姓名不能為空"); this.RuleFor(p => p.Age) .NotEmpty() .WithMessage("年齡不能為空"); this.RuleFor(p => p.Address) .SetValidator(new AddressValidator()); } }
那么如果我們的對象。
model: {
name: undefined,
age: undefined,
address: {
home: undefined,
phone: undefined
}
}
我們該是否也希望這樣設置?
在我分析了后認為在前端js中這種方式不適合,原因是,我們為了簡單而省略了驗證器,而如果這樣的使用方式會讓我們需要定義一個AddressValidator。即使你說我們用一個Validator來代替,那也會讓代碼結構變成
than.ruleFor("name") .NotEmpty() .WithMessage("名稱必填") .MinimumLength(5) .WithMessage("最短長度為5"); than.ruleFor("age") .NotEmpty() .WithMessage("年齡必須") .Number(0, 100) .WithMessage("必須在0-100歲之間"); than.ruleFor("address") .setValidator(new Validator({ model: { home: undefined, phone: undefined }, rule: function (than) { than.ruleFor("home") .NotEmpty() .WithMessage("家庭住址不能為空"); than.ruleFor("iphone") .NotEmpty() .WithMessage("家庭電話不能為空"); } }));
我認為這樣的寫法,簡直糟糕透了,意味着重復又重復。看起來一點都不簡潔了,甚至有點麻煩。
於是我想到了另一種寫法
rule: function (than) { than.ruleFor("name") .NotEmpty() .WithMessage("名稱必填") .MinimumLength(5) .WithMessage("最短長度為5"); than.ruleFor("age") .NotEmpty() .WithMessage("年齡必須") .Number(0, 100) .WithMessage("必須在0-100歲之間"); than.ruleFor("address.home") .NotEmpty() .WithMessage("家庭住址不能為空"); than.ruleFor("address.phone") .NotEmpty() .WithMessage("家庭電話不能為空"); }
咱們key不是叫address嗎?那我們要設置address對象的屬性的時候直接address.propertyName 這樣是不是又簡單了一些?
於是我完成了vuefluentvalidator內部的修改。現我已將他放置在 https://github.com/gxqsd/vuefluentvalidator 你可以下載下來看看有何不同或有何問題,方便我們一起改進。