表单验证
验证是什么
在前后端各自为政的开发模式下,前端和后端需要单独实现各自的Form表单验证
逻辑。Cabloy充分发挥全栈开发的优势,只需定义好JSON Schema
配置信息,就可以同时支持前端与后端的Form表单验证
逻辑。同时,还具备数据清洗
特性,根据JSON Schema
配置信息自动把表单字段
转换成后端所需的数据类型
Cabloy的验证
机制底层采用ajv,建议您对ajv有初步的了解
定义验证信息
以模块a-authsimple
的signin
验证逻辑为例:
1. schemas.js
配置todo
的JSON Schema
,定义两个属性:auth
、password
、rememberMe
JSON Schema
中的属性定义
主要有两个用途:
- 在前端可以自动渲染
Form表单
- 在后端
验证Form表单数据
,并清洗Form表单数据
a-authsimple/backend/src/config/validation/schemas.js
module.exports = app => {
const schemas = {};
schemas.signin = {
type: 'object',
properties: {
auth: {
type: 'string',
ebType: 'text',
ebTitle: 'Your mobile/email',
notEmpty: true,
},
password: {
type: 'string',
ebType: 'text',
ebTitle: 'Your password',
ebSecure: true,
notEmpty: true,
minLength: 6,
},
rememberMe: {
type: 'boolean',
ebType: 'toggle',
ebTitle: 'Remember me',
},
},
};
return schemas;
};
名称 | 说明 |
---|---|
type | 属性类型,如string/number/boolean |
ebType | 属性类型,用于标示前端渲染组件类型,如text/toggle/select |
ebTitle | 属性标题,用于前端渲染 |
notEmpty | 标示此属性是否为空 |
2. meta.js
a-authsimple/backend/src/meta.js
module.exports = app => {
const schemas = require('./config/validation/schemas.js')(app);
return {
validation: {
validators: {
signin: {
schemas: 'signin',
},
},
keywords: {},
schemas: {
signin: schemas.signin,
},
},
};
};
名称 | 说明 |
---|---|
validation.validators | 声明模块所提供的validators 清单 |
validation.keywords | 声明模块所提供的keywords 清单 |
validation.schemas | 声明模块所提供的schemas 清单 |
validator
与schema
的关系
- 一个
validator
可以对应多个schema
,但是一般场景只需提供一个schema
后端验证
模块a-validation
提供了两个验证中间件:validate
、validation
1. validate
中间件validate
根据路由配置的中间件参数,自动进行Form表单
的验证
和清洗
逻辑
a-authsimple/backend/src/routes.js
{ method: 'post', path: 'auth/signup', controller: auth, middlewares: 'validate',
meta: {
validate: { module: 'a-authsimple', validator: 'signup' }
},
},
名称 | 说明 |
---|---|
middlewares: ‘validate’ | 由于validate 是局部中间件,需要显式声明 |
meta.validate | 中间件参数 |
meta.validate.module | 验证器所属模块,缺省为当前模块 |
meta.validate.validator | 需要使用的验证器名称 |
2. validation
全局中间件validation
向ctx.meta
注入对象validation
,便于直接通过代码进行验证
a-authsimple/backend/src/config/passport/auth.js
// validate
await ctx.meta.validation.validate({
module: 'a-authsimple', validator: 'signin', data: body
});
名称 | 说明 |
---|---|
module | 验证器所属模块,缺省为当前模块 |
validator | 需要使用的验证器名称 |
data | 需要验证的Form表单数据 |
前端渲染
模块a-components
提供了一个全局vue组件eb-validate
,主要有两个用途:
- 进行Form表单渲染
- 拦截后端返回的
验证错误信息
,并进行显示
1. 自定义渲染
在eb-validate
内部自定义Form组件布局,这样可以有更强的针对性和灵活性
a-authsimple/front/src/components/signin.vue
<template>
...
<eb-validate ref="validate" :onPerform="onPerformValidate">
<f7-list form no-hairlines-md>
<f7-list-item>
<f7-icon material="person_outline" slot="media"></f7-icon>
<f7-label floating>{{$text('Your mobile/email')}}</f7-label>
<eb-input type="text" :placeholder="$text('Your mobile/email')" clear-button v-model="auth" dataPath="auth"></eb-input>
</f7-list-item>
</f7-list>
</eb-validate>
<f7-list>
<eb-list-button :onPerform="signIn">{{$text('Sign in')}}</eb-list-button>
</f7-list>
...
</template>
<script>
export default {
meta: {
global: false,
},
data() {
return {
auth: null,
password: null,
rememberMe: false,
};
},
methods: {
onPerformValidate() {
return this.$api.post('passport/a-authsimple/authsimple', {
auth: this.auth,
password: this.password,
rememberMe: this.rememberMe,
}).then(user => {
this.$store.commit('auth/login', {
loggedIn: true,
user,
});
this.$meta.vueApp.reload();
});
},
signIn() {
return this.$refs.validate.perform();
},
},
};
- 所有
Form表单字段
都放到组件eb-validate
中 - 当点击按钮
signIn
时,执行validate.perform
,以便触发onPerformValidate
- 在
onPerformValidate
中提交表单,如果有验证错误,会自动显示错误提示
2. 自动渲染
由eb-validate
根据validator
提供的schema
信息自动渲染Form表单
a-authsimple/front/src/pages/reset.vue
<template>
<f7-page>
<eb-navbar :title="$text('Reset password')" eb-back-link="Back"></eb-navbar>
<f7-block>
<eb-validate ref="validate" :auto="true" :data="data" :params="{module:'a-authsimple', validator: 'reset'}" :onPerform="onPerformValidate">
</eb-validate>
<eb-button v-if="!$config.test" :onPerform="onPerformOk">{{$text('OK')}}</eb-button>
</f7-block>
</f7-page>
</template>
<script>
export default {
meta: {
global: false,
},
data() {
return {
data: {
passwordOld: null,
passwordNew: null,
passwordNewAgain: null,
},
};
},
methods: {
onPerformValidate() {
return this.$api.post('auth/reset', {
data: this.data,
}).then(() => {
this.$f7Router.back();
});
},
onPerformOk() {
return this.$refs.validate.perform();
},
},
};
</script>
名称 | 说明 |
---|---|
auto | true:自动渲染 false:自定义渲染 |
data | Form表单数据 |
params | 自动布局参数 |
params.module | 验证器所属模块,默认为当前模块 |
params.validator | 验证器名称 |
评论: