相关视频

验证是什么

在前后端各自为政的开发模式下,前端和后端需要单独实现各自的Form表单验证逻辑。CabloyJS充分发挥全栈开发的优势,只需定义好JSON Schema配置信息,就可以同时支持前端与后端的Form表单验证逻辑。同时,还具备数据清洗特性,根据JSON Schema配置信息自动把表单字段转换成后端所需的数据类型

CabloyJS的验证机制底层采用ajv,建议您对ajv有初步的了解

定义验证信息

以模块test-party的表单formTest为例:

1. 定义Schema

配置formTestJSON Schema,定义表单字段:userNamepasswordpasswordAgainsexlanguageavatarrememberMe

JSON Schema中的字段定义主要有两个用途:

  1. 在前端可以自动渲染Form表单
  2. 在后端验证Form表单数据,并清洗Form表单数据

src/suite-vendor/test-party/modules/test-party/backend/src/config/validation/schemas.js

  1. 1schemas.formTest = {
  2. 2 type: 'object',
  3. 3 properties: {
  4. 4 userName: {
  5. 5 type: 'string',
  6. 6 ebType: 'text',
  7. 7 ebTitle: 'Username',
  8. 8 notEmpty: true,
  9. 9 'x-exists': true,
  10. 10 },
  11. 11 password: {
  12. 12 type: 'string',
  13. 13 ebType: 'text',
  14. 14 ebTitle: 'Password',
  15. 15 ebSecure: true,
  16. 16 notEmpty: true,
  17. 17 minLength: 6,
  18. 18 },
  19. 19 passwordAgain: {
  20. 20 type: 'string',
  21. 21 ebType: 'text',
  22. 22 ebTitle: 'Password again',
  23. 23 ebSecure: true,
  24. 24 notEmpty: true,
  25. 25 const: { $data: '1/password' },
  26. 26 },
  27. 27 sex: {
  28. 28 type: 'number',
  29. 29 ebType: 'select',
  30. 30 ebTitle: 'Sex',
  31. 31 ebMultiple: false,
  32. 32 ebOptions: [
  33. 33 { title: 'Male', value: 1 },
  34. 34 { title: 'Female', value: 2 },
  35. 35 ],
  36. 36 ebOptionsBlankAuto: true,
  37. 37 ebParams: {
  38. 38 openIn: 'page',
  39. 39 closeOnSelect: true,
  40. 40 },
  41. 41 notEmpty: true,
  42. 42 },
  43. 43 language: {
  44. 44 type: 'string',
  45. 45 ebType: 'select',
  46. 46 ebTitle: 'Language',
  47. 47 ebOptionsUrl: '/a/base/base/locales',
  48. 48 ebOptionsUrlParams: null,
  49. 49 ebOptionsBlankAuto: true,
  50. 50 'x-languages': true,
  51. 51 notEmpty: true,
  52. 52 },
  53. 53 avatar: {
  54. 54 type: 'string',
  55. 55 ebType: 'file',
  56. 56 ebTitle: 'Avatar',
  57. 57 ebParams: { mode: 1 },
  58. 58 notEmpty: true,
  59. 59 },
  60. 60 rememberMe: {
  61. 61 type: 'boolean',
  62. 62 ebType: 'toggle',
  63. 63 ebTitle: 'Remember me',
  64. 64 },
  65. 65 },
  66. 66};
名称 说明
type 字段类型,如string/number/boolean
ebType 字段渲染类型,用于标示前端渲染组件类型,如text/toggle/select
ebTitle 字段标题,用于前端渲染
notEmpty 标示此字段是否为空

2. 定义validation

src/suite-vendor/test-party/modules/test-party/backend/src/meta.js

  1. 1validation: {
  2. 2 validators: {
  3. 3 formTest: {
  4. 4 schemas: 'formTest',
  5. 5 },
  6. 6 },
  7. 7 keywords: {
  8. 8 'x-languages': keywords.languages,
  9. 9 },
  10. 10 schemas: {
  11. 11 formTest: schemas.formTest,
  12. 12 },
  13. 13},
名称 说明
validation.validators 声明模块所提供的validators清单
validation.keywords 声明模块所提供的keywords清单
validation.schemas 声明模块所提供的schemas清单

validatorschema的关系

  • 一个validator可以对应多个schema,但是一般场景只需提供一个schema

后端验证

模块a-validation提供了两种验证方式:中间件Api

- 中间件验证

模块a-validation提供了中间件validate,根据路由配置的中间件参数,自动进行Form表单验证清洗逻辑

src/suite-vendor/test-party/modules/test-party/backend/src/routes.js

  1. 1{ method: 'post', path: 'kitchen-sink/form-schema-validation/saveValidation',
  2. 2 controller: 'testKitchensinkFormSchemaValidation',
  3. 3 middlewares: 'validate',
  4. 4 meta: { validate: { validator: 'formTest' } },
  5. 5},
名称 说明
middlewares: ‘validate’ 由于validate是局部中间件,需要显式声明
meta.validate 中间件参数
meta.validate.module 验证器所属模块,缺省为当前模块
meta.validate.validator 需要使用的验证器名称

- Api验证

模块a-validation提供了全局Bean组件validation,便于直接通过代码进行验证

a-authsimple/backend/src/config/passport/auth.js

  1. 1// validate
  2. 2await ctx.bean.validation.validate({
  3. 3 module: 'a-authsimple', validator: 'signin', data: body.data
  4. 4});
名称 说明
module 验证器所属模块,缺省为当前模块
validator 需要使用的验证器名称
data 需要验证的Form表单数据

前端渲染

模块a-components提供了一个全局vue组件eb-validate,主要有两个用途:

  1. 进行Form表单渲染
  2. 拦截后端返回的验证错误信息,并进行显示

- 自动渲染

eb-validate根据validator提供的schema信息自动渲染Form表单

src/suite-vendor/test-party/modules/test-party/front/src/kitchen-sink/pages/form-schema-validation/formSchemaAuto.vue

  1. 1<eb-validate v-if="item" ref="validate" auto :data="item" :params="validateParams" :onPerform="onPerformValidate" @submit="onFormSubmit">
  2. 2</eb-validate>
名称 说明
auto true:自动渲染 false:自定义渲染
data Form表单数据
params 自动布局参数
params.module 验证器所属模块,默认为当前模块
params.validator 验证器名称
onPerform 在这里调用后端API接口
submit 响应Submit事件
  1. 当点击按钮Save或者响应Submit事件时,执行eb-validate的方法perform,从而触发eb-validateonPerform
  2. onPerform中调用后端API接口,如果有验证错误,就会自动显示出来

- 自定义渲染

eb-validate内部自定义Form组件布局,这样可以有更强的针对性和灵活性

src/suite-vendor/test-party/modules/test-party/front/src/kitchen-sink/pages/form-schema-validation/formSchemaCustom.vue

  1. 1<eb-validate v-if="item" ref="validate" :auto="false" :data="item" :params="validateParams" :onPerform="onPerformValidate">
  2. 2 <eb-list form inline-labels no-hairlines-md @submit="onFormSubmit">
  3. 3 <eb-list-item-validate dataKey="userName"></eb-list-item-validate>
  4. 4 <eb-list-item-validate dataKey="password"></eb-list-item-validate>
  5. 5 <eb-list-item-validate dataKey="passwordAgain"></eb-list-item-validate>
  6. 6 <eb-list-item-validate dataKey="sex"></eb-list-item-validate>
  7. 7 <eb-list-item-validate dataKey="birthday"></eb-list-item-validate>
  8. 8 <eb-list-item-validate dataKey="language"></eb-list-item-validate>
  9. 9 <eb-list-item-validate dataKey="avatar"></eb-list-item-validate>
  10. 10 <f7-list-item v-if="item.avatar">
  11. 11 <img class="avatar avatar48" :src="getAvatarUrl(item.avatar,48)">
  12. 12 </f7-list-item>
  13. 13 <eb-list-item-validate dataKey="rememberMe"></eb-list-item-validate>
  14. 14 <eb-list-item-validate dataKey="motto"></eb-list-item-validate>
  15. 15 </eb-list>
  16. 16</eb-validate>