首页 > 技术文章 > element UI form表单动态增减表单项

wangziye 2020-08-04 09:51 原文

element UI

form表单动态增减表单项

最近接到一个需要自定义表单项的需求,同时需要对新增项进行校验,我们这个项目采用的是element这个UI组件,所以使用的内置的form组件实现功能,但是发现一个坑,折腾了一两个小时,记录一下

下面是官网的例子
<el-form :model="dynamicValidateForm" ref="dynamicValidateForm">
    <el-form-item
        v-for="(domain, index) in dynamicValidateForm.domains"
        :label="'域名' + index"
        :key="domain.key"
        :prop="'domains.' + index + '.value'"
        :rules="{
          required: true, message: '域名不能为空', trigger: 'blur'
        }"
     >
        <el-input v-model="domain.value"></el-input>
     </el-form-item>
  </el-from>
  
  <script>
  export default {
    data() {
      return {
        dynamicValidateForm: {
          domains: [{
            value: ''
          }],
          email: ''
        }
      };
    },
  }
</script>

这里的prop 属性设置是有讲究的,如果你没有按照这个格式设置,下面会一直报找不到匹配值的错误,或者是校验规则一直error,根本无法通过校验。

:prop="'domains.' + index + '.value'"

这里的domains 是表单from绑定值下面循环体的key,index为当前下标,value是当前循环对象v-modal绑定的key。

我们再到element ui 源码中看一下他是如何匹配这个prop

fieldValue() {
    const model = this.form.model;
    if (!model || !this.prop) { return; }

    let path = this.prop;
    if (path.indexOf(':') !== -1) {
      path = path.replace(/:/, '.');
    }

    return getPropByPath(model, path, true).v;
  }

这里我们发现他是通过getPropByPath 这个方法去获取匹配值,三个参数,第一个就是我们form的绑定值,(即我们示例中的dynamicValidateForm) 第二个就是formItem中绑定的prop (即:prop="'domains.' + index + '.value'")

下面是具体的getPropByPath 匹配方法

export function getPropByPath(obj, path, strict) {
  let tempObj = obj;
  path = path.replace(/\[(\w+)\]/g, '.$1');
  path = path.replace(/^\./, '');

  let keyArr = path.split('.');
  let i = 0;
  for (let len = keyArr.length; i < len - 1; ++i) {
    if (!tempObj && !strict) break;
    let key = keyArr[i];
    if (key in tempObj) {
      tempObj = tempObj[key];
    } else {
      if (strict) {
        throw new Error('please transfer a valid prop path to form item!');
      }
      break;
    }
  }
  return {
    o: tempObj,
    k: keyArr[i],
    v: tempObj ? tempObj[keyArr[i]] : null
  };
};

我们看到报错 please transfer a valid prop path to form item! 原因就是prop 没有匹配到数据。prop的规则是根据prop,通过对from的绑定值一层层遍历往下去找,找到了就返回,没找到就会丢出一个error

推荐阅读