封装一个动态表单吧

经常做后台的小伙伴儿可能经常要遭遇各种表单结构,input,select,时间、日期插件等等,各种属性配置到吐,今天就带大家来封装一个可复用表单。表单参考了网上的一些例子,再结合自己的需求,封装了一个自己的业务表单组件。
先上图:


QQ截图20201118163834.png

首先给大家看一下结构布局:
我们现实放了一个form表单。然后利用el-form-item来循环遍历,给每一个el-form-item设置动态label,动态rules(校验规则)以及相对应的prop。
然后我们给每一种类型的表单元素添加动态disabled的属性,控制可编辑状态。
给属性绑定动态表单值,并且添加placeholder提示语;
对于select,checkbox等多值域绑定的表单元素,配置项中提供options属性。
然后我们的图片上传用的是我们之前封装的图片上传组件,传递一个绑定值和一个可编辑状态即可。
最后我们给每个表单元素添加了一个tooltip,用于提示用户每一个表单元素要填写的内容或者提示语。对于每一个label标签,我们也做了最基本的处理,大于四个字我们就给变成4字加省略号,通过tooltip来查看标签名称。


下面是组件内的方法及属性定义


我们在页面里使用时,只需要调用一下校验方法,看是否通过校验即可,这里的表单校验方法返回的是一个promise,所以 这里用async 和 await搭配使用来renturn校验flag。
再来看我们的组件应用页面;(这里的具体属性可根据element文档自行查看。)



我的rules校验方法是在网上看到的一个大神的校验方法,了解详细,拿来即用,给大家看一下。

//Check方法
//校验规则列表(可扩展)
const rules = {
  URL(url) {
    const regex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?"\\+&%$#=~_-]+))*$/
    return valid(url, regex, "URL格式不正确")
  },

  LowerCase(str) {
    const regex = /^[a-z]+$/
    return valid(str, regex, "只能输入小写字母")
  },

  UpperCase(str) {
    const regex = /^[A-Z]+$/
    return valid(str, regex, "只能输入大写字母")
  },

  Alphabets(str) {
    const regex = /^[A-Za-z]+$/
    return valid(str, regex, "只能输入字母")
  },

  Email(email) {
    const regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
    return valid(email, regex, "邮箱地址格式不正确")
  },

  Mobile(mobile) {
    const regex = /^1\d{10}$/
    return valid(mobile, regex, "手机号格式不正确")
  },

  Phone(phone) {
    const regex = /^(0\d{2,3})?-?\d{7,8}$/
    return valid(phone, regex, "电话号码格式不正确")
  },

  Postcode(postcode) {
    const regex = /^[0-9][0-9]{5}$/
    return valid(postcode, regex, "邮编格式不正确")
  },

  Number(num) {
    const regex = /^\d+$/
    return valid(num, regex, "只能输入纯数字")
  },

  Fax(fax) {
    const regex = /^(\d{3,4}-)?\d{7,8}$/
    return valid(fax, regex, "传真格式不正确")
  },

  Int(num) {
    const regex = /^((0)|([1-9]\d*))$/
    return valid(num, regex, "只能输入非负整数")
  },

  IntPlus(num){
    const regex = /^[1-9]\d*$/
    return valid(num, regex, "只能输入正整数")
  },

  Float1(num){
    const regex = /^-?\d+(\.\d)?$/
    return valid(num, regex, "只能输入数字,最多一位小数")
  },

  Float2(num){
    const regex = /^-?\d+(\.\d{1,2})?$/
    return valid(num, regex, "只能输入数字,最多两位小数")
  },

  Float3(num){
    const regex = /^-?\d+(\.\d{1,3})?$/
    return valid(num, regex, "只能输入数字,最多三位小数")
  },
  
  FloatPlus3(num){
    const regex = /^\d+(\.\d{1,3})?$/
    return valid(num, regex, "只能输入数字,最多三位小数")
  },

  Encode(code){
    const regex = /^(_|-|[a-zA-Z0-9])+$/
    return valid(code, regex, "编码只能使用字母、数字、下划线、中划线")
  },

  Encode2(code){
    const regex = /^[a-zA-Z0-9]+$/
    return valid(code, regex, "编码只能使用字母、数字")
  },

  Encode3(code){
    const regex = /^(_|[a-zA-Z0-9])+$/
    return valid(code, regex, "编码只能使用字母、数字、下划线")
  },

  IdCard(code){
    const regex = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
    return valid(code, regex, "请输入正确的身份证号码")
  },
  
  USCC(code){
    const regex = /^[0-9A-Z]{18}/
    return valid(code, regex, "请输入正确的社会信用号")
  },
  
  CarNum(code){
    const regex = /^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$/i
    return valid(code, regex, "请输入正确的车牌号")
  },
  
  CNandEN(code){
    const regex = /^[a-zA-Z\u4e00-\u9fa5]+$/
    return valid(code, regex, "只能使用中文、英文")
  },
  
  MobileOrPhone(val){
    const result = /^1\d{10}$/.test(val) || /^(0\d{2,3})?-?\d{7,8}$/.test(val)
    return valid(result, null, "手机或电话号格式不正确")
  }
}

//val:String 要校验的值
//regex:RegExp 校验正则,不是正则时val作为result的值
//msg:String 校验不通过的错误信息
function valid(val, regex, msg){
  return {result: regex instanceof RegExp? regex.test(val) : !!val, errMsg: msg}
}

//required:Boolean 是否必填项,选填,默认"true"
//type:String/Function 校验类型,选填,
//     String时必须是上面rules中存在的函数名,
//     Function时只接收一个参数(输入值),返回格式: {result:Boolean, errMsg:String}
//trigger:String 触发动作,选填,默认"blur"
//nullMsg:String 未输入的提示语,选填,required=true时有效
export function Check(required=true, type, trigger="blur", nullMsg="该字段为必填项"){
  const rule = { required: !!required, trigger}

  let check = null
  if(typeof type === "function"){
    check = type
  }else{
    check = type ? rules[type+""] : null
  }

  if(check){//存在规则时添加规则
    rule.validator = (r, v, c) => {
      const {result, errMsg} = check(v)
      if(required){
        //必填项: null,undefined,"","  " 都算无输入内容
        return (v==null || (v+"").trim()==="") ? c(new Error(nullMsg)) : result ? c() : c(new Error(errMsg))
      }
      //选填项: null,undefined,"" 都算无输入内容,"  "会被校验
      return (v==null || (v+"")==="" || result) ? c() : c(new Error(errMsg))
    }
  }else{
    rule.message = nullMsg
  }

  return [rule]
}

校验方法很完美。


QQ截图20201118170100.png

写到这里,我们的一个简单的form表单封装就完成了。有需要的小伙伴儿可以添加更多的元素进去,例如开关,例如radio-button等等,这里的封装元素也只添加了最基本的元素,想要的更多可以自行添加,示例都在上面。大家觉得对你有帮助的,可以点个赞!!!谢谢!!

你可能感兴趣的:(封装一个动态表单吧)