ElementUI el-form表单多层数组的校验

问题描述

提示:这里描述项目中遇到的问题:

ElementUI el-form表单多层数组的校验


页面效果:

在这里插入图片描述


数据结构:

addform: {
        code: '',
        type: '',
        value: '',
        state: 1,
        remark: '',
        fieldList: [
          {
            fieldCode: '',
            resolverEntities: [{
  resolverType: '', 
  resolverConfigOne: '', 
  resolverConfigTwo: '' 
}]
          }
        ]
      }

HTML:

<el-form ref="addform" :rules="formRules" :model="addform" size="small">
        <el-form-item label="标识:" prop="code">
          <el-input
            v-model="addform.code"
            placeholder="请输入"
            autocomplete="off"
            clearable
          />
        </el-form-item>
        <el-row>
          <el-col :span="8">
            <el-form-item label="类型:" prop="type">
              <el-select v-model="addform.type" placeholder="请选择">
                <el-option
                  v-for="item in typeOptions"
                  :key="item.code"
                  :label="item.name"
                  :value="item.code"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="16">
            <el-form-item class="state-box" label="状态:" prop="state">
              <el-switch
                v-model="addform.state"
                active-color="#13ce66"
                inactive-color="#ff4949"
                :active-value="1"
                :inactive-value="2"
              >
              </el-switch>
            </el-form-item>
          </el-col>
        </el-row>

        <div class="custom-rule-box">
          <p>自定义解码字段</p>
          <ul>
            <li
              v-for="(customRuleItem, customRuleIndex) in addform.fieldList"
              :key="customRuleIndex"
            >
              <el-form-item
                class="field-name"
                label="字段名:"
                :prop="`fieldList.${customRuleIndex}.fieldCode`"
                :rules="formRules.fieldCode"
              >
                <el-input
                  v-model="addform.fieldList[customRuleIndex].fieldCode"
                  placeholder="请输入"
                  autocomplete="off"
                  clearable
                />
              </el-form-item>
              <div
                class="decode-rule-list"
                v-for="(
                  decodeRuleItem, decodeRuleIndex
                ) in customRuleItem.resolverEntities"
                :key="decodeRuleIndex"
              >
                <el-row :gutter="24">
                  <el-col :span="5">
                    <el-form-item
                      label=""
                      :prop="`fieldList.${customRuleIndex}.resolverEntities.${decodeRuleIndex}.resolverType`"
                      :rules="formRules.resolverType"
                    >
                      <el-select
                        v-model="decodeRuleItem.resolverType"
                        placeholder="请选择"
                      >
                        <el-option
                          v-for="item in decodeRuleOptions"
                          :key="item.code"
                          :label="item.name"
                          :value="item.code"
                        >
                        </el-option>
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <template v-if="decodeRuleItem.resolverType">
                    <el-col :span="8">
                      <el-form-item
                        :label="
                          computedResolverConfigOneLabel(
                            decodeRuleItem.resolverType
                          )
                        "
                        :prop="`fieldList.${customRuleIndex}.resolverEntities.${decodeRuleIndex}.resolverConfigOne`"
                        :rules="formRules.resolverConfigOne"
                      >
                        <el-input
                          v-model="decodeRuleItem.resolverConfigOne"
                          placeholder="请输入"
                          autocomplete="off"
                          clearable
                        />
                      </el-form-item>
                    </el-col>

                    <el-col :span="8">
                      <el-form-item
                        :label="
                          computedResolverConfigTwoLabel(
                            decodeRuleItem.resolverType
                          )
                        "
                        :prop="`fieldList.${customRuleIndex}.resolverEntities.${decodeRuleIndex}.resolverConfigTwo`"
                        :rules="formRules.resolverConfigTwo"
                      >
                        <el-input
                          v-model="decodeRuleItem.resolverConfigTwo"
                          placeholder="请输入"
                          autocomplete="off"
                          clearable
                        />
                      </el-form-item>
                    </el-col>
                  </template>
                  <el-col :span="3" class="decode-rule-operate">
                    <img
                      v-if="customRuleItem.resolverEntities.length > 1"
                      src="@/assets/images/common/delete.png"
                      alt=""
                      class="deleteImg"
                      @click="
                        handleDeleteResolver(customRuleIndex, decodeRuleIndex)
                      "
                    />
                    <img
                      src="@/assets/images/common/add.png"
                      alt=""
                      class="addImg"
                      @click="
                        handleAddResolver(customRuleIndex, decodeRuleIndex)
                      "
                    />
                  </el-col>
                </el-row>
              </div>
            </li>
          </ul>
          <div class="add-btn">
            <img
              src="@/assets/images/common/add.png"
              alt=""
              class="deleteImg"
              @click="handleAddField"
            />新增
          </div>
        </div>
      </el-form>

总结:

重点在于 el-form-item prop绑定,参考如下示例

:prop=“fieldList.${customRuleIndex}.fieldCode

:prop=“fieldList.${customRuleIndex}.resolverEntities.${decodeRuleIndex}.resolverConfigOne


### 使用 `el-form-item` 对嵌套多层表单进行校验 Element UI 的 `el-form` 和 `el-form-item` 组件提供了强大的功能来处理复杂的表单验证逻辑。对于具有嵌套结构的表单,可以利用 Vue.js 的响应式特性以及 Element 提供的 API 来实现全面而灵活的数据验证。 #### 定义嵌套数据模型 为了支持多层次的输入项,在定义初始状态时应构建相应的对象树形结构[^1]: ```javascript data() { return { form: { outerField: '', innerForms: [ { nestedField: '' }, // 可以有多个子级条目... ] } }; } ``` #### 创建动态添加/移除字段的方法 允许用户通过界面操作增加或减少特定层级下的项目数量[^2]: ```javascript methods: { addInnerForm() { this.form.innerForms.push({nestedField: ''}); }, removeInnerForm(index) { this.form.innerForms.splice(index, 1); } } ``` #### 配置规则并应用到每一层 针对不同级别的属性设置独立却又相互关联的检验条件: ```javascript rules: { 'outerField': [{ required: true, message: '请输入外层必填项', trigger: 'blur' }], 'innerForms.*.nestedField': [{ required: true, message: '请输入内层必填项', trigger: 'change' }] }, ``` 注意这里的 `'innerForms.*.nestedField'` 表达方式用于匹配数组中的每一个元素作为单独的对象来进行验证。 #### 渲染模板展示层次化布局 使用 v-for 指令遍历集合渲染出对应的 HTML 结构,并确保每个 `el-form-item` 正确绑定其所属路径上的 prop 属性值: ```html <template> <el-form :model="form" :rules="rules"> <!-- 外部表单--> <el-form-item label="外部字段" prop="outerField"> <el-input v-model="form.outerField"></el-input> </el-form-item> <!-- 循环创建内部表单--> <div v-for="(item, index) in form.innerForms" :key="index"> <el-form-item :label="'内部字段-' + (index+1)" :prop="'innerForms.' + index + '.nestedField'" > <el-input v-model="item.nestedField"></el-input> <!-- 添加删除按钮控制 --> <button @click.prevent="removeInnerForm(index)">-</button> </el-form-item> <!-- 如果需要更深层次,则继续按照此模式扩展 --> </div> <!-- 动态新增按钮 --> <button type="button" @click="addInnerForm">+</button> <el-button type="primary" native-type="submit">提交</el-button> </el-form> </template> ``` 上述代码片段展示了如何在一个包含两层结构的表单中实施有效的客户端侧验证机制。当涉及到更加复杂的情况时(比如三层甚至更多),只需遵循相同的原则逐级深入即可完成相应配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值