簡單講一下這個egg-validate
安裝
npm install --save egg-validate
啟用
// config/plugin.js
exports.validate = {
enable: true,
package: 'egg-validate',
};
配置
// config/config.default.js
exports.validate = {
// convert: false,
// validateRoot: false,
};
用途嘛,就是對參數進行檢驗。比如檢驗一個用戶名是不是字符串,可以這么寫,
ctx.validate({ userName: 'string' });
默認就會對ctx.request.body進行檢驗
你想檢驗ctx.query的話,那就ctx.validate({ userName: 'string' }, ctx.query);
,params就ctx.params。
它會在檢驗失敗的拋出一個異常,沒有捕獲的話,會返回一個422錯誤。
第二種使用方法:
let errs = app.validator.validate({ userName: 'string' }, ctx.request.body);
ctx.validate檢驗不通過會拋出異常,而app.validator.validate檢驗不通過會返回錯誤。你可以自己選擇要對這個錯誤怎么處理,是不管呢還是返回前端。
關於校驗規則rule
完全和parameter的校驗規則一樣。建議直接看readme文檔,雖然是英文的,但是配着翻譯看個7788是差不多的。
ctx.validate({ userName: 'string' });
這里面的rule就是{ userName: 'string' },它會這么檢驗,首先判斷這個userName有沒有在ctx.request.body里面,沒有就跑出參數不存在、然后是userName不能為空、然后得是string。有一個不符合都會拋出錯誤。
你想判斷一個用戶的信息是否正確可以這么寫:
ctx.validate({
userName: 'userName', // 自定義的校驗規則
password: 'password', // 自帶的校驗規則
sex: ['men', 'women'], // 性別是men或者women
age: {
type: 'number', // 年齡范圍0-120
min: 0,
max: 120
}
});
這里有個坑,年齡怎么填都會報格式錯誤,這是因為配置的時候默認把參數轉型關了,配置回來就好:
config.validate = { // 配置參數校驗器,基於parameter
convert: true, // 對參數可以使用convertType規則進行類型轉換
// validateRoot: false, // 限制被驗證值必須是一個對象。
};
主要使用的幾個點,核心使用
1、使用自帶的校驗規則:
password: 'password'
,或者
password: {
type: 'password',
allowEmpty: true // 設置密碼為空,作為示例亂寫一下。。
}
校驗規則有這些,文檔很詳細了:
2、自定義的校驗規則
通過app.validator.addRule添加:
// 校驗用戶名是否正確
app.validator.addRule('userName', (rule, value)=>{ // value就是待檢驗的數據
if (/^\d+$/.test(value)) {
return "用戶名應該是字符串";
}
else if (value.length < 3 || value.length > 10) {
console.log("用戶名的長度應該在3-10之間");
}
});
這個可以直接放在app.js里面。return的就是錯誤消息message,但是err不止這個,還有錯誤字段啊啥的、都會幫我們自動包裝好。
3、app.validator.addRule('userName', (rule, value)=>{
里面這個字符串'userName'
添加了這個規則就可以直接使用ctx.validate({userName: 'userName'});
。
或者
ctx.validate({userName: {
type: 'userName',
isAdmin: true'
});
4、app.validator.addRule('userName', (rule, value)=>{
里面這個rule
像3、那樣的規則就是把
{
type: 'userName',
isAdmin: true'
}
直接賦值給rule傳過來
{ type: 'userName', isAdmin: true }
然后你可以自己加判斷,比如如果 isAdmin的話,管理員用戶名不能有中文啊,長度至少5位啊啥的。
5、在哪里addRule
上面寫的是推薦大家在app.js里面addRule。為什么呢?
當然你可以在任何你能取到app的地方調用app.validator.addRule('userName', (rule, value)=>{
去addRule。
但是不建議在controller里面addRule。因為controller在每次路由匹配到之后都會進行實例化,所以請求了n遍,也就執行了這個addRule n遍。
而且代碼會變的很臃腫。不易於管理。
在app.js addRule當然是很棒的,只在app加載時add一次。
但是問題又來了,隨着rule變多,你在app.js里面寫了很多代碼都是關於addRule的,但是app.js又不止要寫addRule、還寫了一些別的,那看起來多亂啊。也不利於管理。
如果將來新的項目要用到相同的校驗規則難道還有從app.js里面手動拷貝嗎。
所以下面接着講eggjs基於egg-validate的定制化升級
eggjs基於egg-validate的定制化升級
我們希望能達到怎么樣的一個效果呢?
- app.js里面少寫一些代碼,最好就寫一兩行,做個配置這樣子
- 對於所有的自定義校驗規則獨立出文件夾,可以取名validate,就丟在app/下面
- 針對相似的校驗規則進一步抽象成文件,就叫做user.js這樣,丟在app/validate/下面
- 針對某一條特定的校驗規則,如校驗用戶的userName就丟在app/validate/user.js里面
- 然后保持egg-validate的使用規則不變,原來是ctx.validate現在還是ctx.vallidate。同時其他的插件、配置不受影響。這叫做代碼侵入性小。
下面照着這幾個目標實現代碼
首先把app.js里面導入模塊寫出來
我們使用Loader來加載validate下面的所有文件:
const path = require('path');
module.exports = app => {
// 你的其它代碼,balabala
// 加載所有的校驗規則
const directory = path.join(app.config.baseDir, 'app/validate');
app.loader.loadToApp(directory, 'validate');
}
然后建立實際的校驗規則文件
建立app/validate/user.js文件
寫入以下代碼
module.exports = app =>{
let { validator } = app;
// 校驗用戶名是否正確
validator.addRule('userName', (rule, value)=>{
console.log(rule);
if (/^\d+$/.test(value)) {
return "用戶名應該是字符串";
}
else if (value.length < 3 || value.length > 10) {
console.log("用戶名的長度應該在3-10之間");
}
});
// 添加自定義參數校驗規則
validator.addRule('123', (rule, value) => {
if (value !== '123'){
return 'must be 123';
}
});
};
這里validator.addRule和原來一樣,只是為了少寫代碼,之前把validator取出來了:
let { validator } = app;
這樣定制化升級就完成了。之后需要再新建檢驗規則就寫在validate里面,某一類相似校驗規則要復用就直接拷貝文件就好了。
有什么問題歡迎留言評論,看到盡量會回復。。。