JavaScript ES6 | 使用开展运算符完成全平台校验重名逻辑封装

作者 : 开心源码 本文共3439个字,预计阅读时间需要9分钟 发布时间: 2022-05-14 共247人阅读

背景

在应用系统中创立业务对象时,需要填写表单,对于对象的名称、标识等,全平台往往有统一的功能规范。
例如:

  • 名称:统一为中文、不超过50字符、不能为空、不能与现有平台重复
  • 标识:统一为英文,不超过50字符、不能为空、不能与现有平台重复
    交互逻辑一致(填写名称/标识后,调用后端接口进行判断,后端查询数据库后,返回能否存在重名数据(true/false),存在重复则报表单校验错误,不允许表单提交),前台使用的组件也一致(使用element-UIForm组件),公共逻辑清晰,于是我尝试进行统一的规则校验逻辑方法封装,简化了大量重复代码,在使用时用开展运算符spread(...)进行引入,保证了代码的优雅和简洁。

开展(spread)运算符

开展运算符是JavaScript ES6的特性,可以用于数组、字符串、对象的解构赋值。
具体使用逻辑请参考:扩展运算符

校验逻辑方法定义

校验函数封装

定义方法入参:
1、资源英文名称
用于拼接调用后台RESTful接口,例如:校验应用重复,后台定义接口URI为:
/api/applications/nameOrKeyExisted,此时资源英文名称为applications
2、资源中文名
用于页面提醒回显,例如:表单中应用名称没有填写,提醒:“请填写应用名称”,应用名称已存在,提醒:“应用名称重复”,此时资源中文名为“应用”
3、附加参数

  • 有些资源限定为某类型下不能重复,或者某个领域内不能重复,在调用判重接口时需要传递给后台。
  • prop参数,用于表单绑定的prop定义,假如不传,默认为name和key,允许传入自己设置值。
    方法前台源码(定义在通用的util.js中,在Vue工程中可以在main.js引入到全局中。)

定义方法返回:
返回对象,对象中,键对应表单 prop属性,值是一个数组,包括多种规则(特殊字符校验、非空校验、重名校验等)
utils.js:

/** * @entity 校验实体资源 * @entityName 校验实体中文名 * @options  调用校验接口,额外参数传递 */function getRules(entity, entityName,options) {  let name = options?.nameProp || 'name'  let key = options?.keyProp || 'key'  let rules = {};  rules[name] = validateRules(    'name',    entity,    entityName,    options?.params  );  rules[key] = validateRules(    'key',    entity,    entityName,    options?.params  );  return rules;}function validateRules(field, entity, entityName,extraParams) {  let rules = [];  let requiredRule = {    required: true,    message: `请输入${entityName}${field === 'key' ? '标识' : '名称'}`,    trigger: "blur",  };  if (field == 'key') {    let maxLengthRule = { max: 40, message: "不得超过40个字符", trigger: "blur" };    rules.push(maxLengthRule);    rules.push({ validator: keyValidator, trigger: ['blur', 'change'] })  } else {    let maxLengthRule = { max: 16, message: "不得超过16个字符", trigger: "blur" };    rules.push(maxLengthRule);    rules.push({ validator: nameValidator, trigger: ['blur', 'change'] })  }  rules.push(requiredRule);  rules.push(    {      validator:        nameOrKeyExistedValidator,      entity: entity,      extraParams: extraParams,      entityName: entityName,      trigger: "blur",    }  );  return rules;}const keyValidator = (rule, value, callback) => {  const reg = /^[a-zA-Z0-9_]+$/  if (!reg.test(value)) {    callback(new Error('仅支持英文、数字和下划线'))  } else {    callback();  }}const nameValidator = (rule, value, callback) => {  const reg = /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/  if (!reg.test(value)) {    callback(new Error('仅支持中文、英文、数字和下划线'))  } else {    callback();  }}const nameOrKeyExistedValidator = (rule, value, callback) => {  if (rule.oldVal && rule.oldVal === value) {    callback();  } else {    nameOrKeyExisted(rule.entity, rule.field, value,rule.extraParams).then(res => {      if (res) {        if (rule.field === "name") {          callback(`${rule.entityName}名称重复`)        } else {          callback(`${rule.entityName}标识重复`)        }      } else {        callback();      }    })  }}
  • 编辑实体时的判断逻辑(传入oldVal,避免错误的报错)
    这里的逻辑暂时没想到比较好的处理方法,所以写的比较恶心,由于原价的值可能是异步拿到的,所以需要手动赋值。传入oldVal后,当表单输入值与原价的值一致时,就不会调用后台判重接口了。
  created() {    if (this.isEdit) {      this.rules.name[3].oldVal = this.ruleForm.name      this.rules.key[3].oldVal = this.ruleForm.key    }  }

封装后台axios请求:

export function nameOrKeyExisted(entityName, type, data, params) {  let queryParams ={};  if (params) {     queryParams = {      ...params,      type: type,      nameOrKey: data     }  } else {     queryParams = {      type: type,      nameOrKey: data    }  }  return $get(`/api/${entityName}/nameOrKeyExisted`, queryParams)}

请求的封装需要后台的配合~(由于这个平台后台也是由我一手包办的,所以当然不在话下啦)

  • 后台定义接口时,只要要注意后台URI和返回值一致即可以了。

使用

 <el-form :model="esseForm" :rules="esseFormRules" ref="baseInfoForm">...</el-form>
 esseFormRules: {        type: [          {            required: true,            message: '请选择实体类型',            trigger: 'blur'          }        ],        ...this.$utils.validate.getRules('sem-esses', '实体',{params: {user: a}})      },

如上,使用开展运算符,将返回的结果赋值到rules对象中,名称和标识的规则由通用的校验函数根据入参生成,该方法已经挂载到全局的$utils上,无需额外的引入成本,一次性生成了对于名称、标识的所有校验。

小结

本方法适用于校验逻辑雷同、并且需要实体创立和校验的平台,假如功规调整,也能快速适应(例如长度从限制50字符改为限制100字符),节约时间。
缺陷:校验规则函数的灵活度往往与复杂度成正比,假如需要更多特殊的校验,需要考虑能否有必要修改校验函数,可能不太适用这种方法,假如创立表单的校验逻辑差异较大,就还是建议为每个表单定义自己的rules规则。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » JavaScript ES6 | 使用开展运算符完成全平台校验重名逻辑封装

发表回复