使用antd的form表单组件实现动态表单,数据层次导致校验问题踩坑!!!!

<a-form :model="weeklyState.formModel" ref="formRef">
  <div class="my-page">
    <div class="form-top">
      <a-row>
        <a-col :span="12">
          <a-form-item label="区域名称" :rules="[{ required: true, message: '请选择区域名称!', trigger: 'blur' }]"
            name="regionName">
            <a-select v-model:value="weeklyState.formModel.regionName" placeholder="请选择区域名称" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="时间范围" :rules="[{ required: true, message: '请选择时间范围!', trigger: 'blur' }]" name="time">
            <a-date-picker style="width: 200px" v-model:value="weeklyState.formModel.time" picker="week"
              :format="weekFormat" @change="handleWeekChange" />
          </a-form-item>
        </a-col>
      </a-row>
    </div>

    <div class="module-item" v-for="(item, index) in weeklyState.formModel.weekWorkSummaryDetailList" :key="index">
      <div class="form-content">
        <a-form-item label="模块标题" :rules="[{ required: true, message: '请输入模块标题!', trigger: 'blur' }]"
          :name="['weekWorkSummaryDetailList',index, 'title']">
          <a-col :span="24">
            <a-input v-model:value="weeklyState.formModel.weekWorkSummaryDetailList[index].title"
              placeholder="请输入模块标题" />
          </a-col>
        </a-form-item>
        <a-form-item label="模块内容" :name="['weekWorkSummaryDetailList',index, 'content']"
          :rules="[{ required: true, message: '请输入模块内容!', trigger: 'blur' }]">
          <a-col :span="24">
            <a-textarea :rows="4" placeholder="请输入模块内容" v-model:value="
                              weeklyState.formModel.weekWorkSummaryDetailList[index].content
                          " />
          </a-col>
        </a-form-item>
      </div>
      <a v-if="!currentData.taskId" class="del" @click="handlerDeleteFormItem(index)">删除</a>
    </div>
  </div>
</a-form>

这是一个动态表单,数据结构如下

const weeklyState = reactive({
        formModel: {
            time: '',
            timeFrameList: [],
            regionName: undefined,
            weekWorkSummaryDetailList: []
        }
    })

其中区域名称和时间范围与下面模块标题/模块内容是一对多关系,也就是说一个区域对应多个模块,踩坑示范

<a-form :model="weeklyState.formModel" ref="formRef">
  <div class="my-page">
    <div class="form-top">
      <a-row>
        <a-col :span="12">
          <a-form-item label="区域名称" :rules="[{ required: true, message: '请选择区域名称!', trigger: 'blur' }]"
            name="regionName">
            <a-select v-model:value="weeklyState.formModel.regionName" placeholder="请选择区域名称" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="时间范围" :rules="[{ required: true, message: '请选择时间范围!', trigger: 'blur' }]" name="time">
            <a-date-picker style="width: 200px" v-model:value="weeklyState.formModel.time" picker="week"
              :format="weekFormat" @change="handleWeekChange" />
          </a-form-item>
        </a-col>
      </a-row>
    </div>

    <div class="module-item" v-for="(item, index) in weeklyState.formModel.weekWorkSummaryDetailList" :key="index">
      <div class="form-content">
        <a-form-item label="模块标题" :rules="[{ required: true, message: '请输入模块标题!', trigger: 'blur' }]"
          :name="[index, 'title']">
          <a-col :span="24">
            <a-input v-model:value="weeklyState.formModel.weekWorkSummaryDetailList[index].title"
              placeholder="请输入模块标题" />
          </a-col>
        </a-form-item>
        **

## 请注意这里的动态name绑定,由于form表单绑定的值:model="weeklyState.formModel"只到formModel这一层,导致触发校验时在formModel找不到name为title和content的字段,导致校验一直出错,但是打印formModel却可以看到数据,

**
        <a-form-item label="模块内容" :name="[,index, 'content']"
          :rules="[{ required: true, message: '请输入模块内容!', trigger: 'blur' }]">
          <a-col :span="24">
            <a-textarea :rows="4" placeholder="请输入模块内容" v-model:value="
                              weeklyState.formModel.weekWorkSummaryDetailList[index].content
                          " />
          </a-col>
        </a-form-item>
      </div>
      <a v-if="!currentData.taskId" class="del" @click="handlerDeleteFormItem(index)">删除</a>
    </div>
  </div>
</a-form>

解决方案只需在数组中再加一个路径,指引组件这个数据的指向

 :name="['weekWorkSummaryDetailList', index, 'content']"
  :name="['weekWorkSummaryDetailList', index, 'title']"

这样修改后,a-form-item 能够正确识别表单项在 formModel 中的路径,从而避免 please transfer a valid name path to form item! 这个错误。即可以解决,可以正常通过校验
2025-02-27补充一版,如果多层嵌套校验时name属性需要按顺序将遍历的数组名称写进去以及对应的索引

  <div class="stage-item" v-for="(item, index) in state.templateStageList" :key="item.uid">
                            <a-row :gutter="16">
                                <a-col :span="11">
                                    <a-form-item
                                        label="项目阶段名称"
                                        :name="['templateStageList', index, 'stageName']"
                                        :rules="state.stageRules.stageName"
                                    >
                                        <a-input v-model:value="item.stageName" placeholder="请输入" :maxlength="20" />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="11">
                                    <a-form-item
                                        label="项目阶段序号"
                                        :name="['templateStageList', index, 'serialNumber']"
                                        :rules="state.stageRules.serialNumber"
                                    >
                                        <a-input
                                            v-model:value="item.serialNumber"
                                            placeholder="请输入"
                                            :maxlength="4"
                                            :disabled="!!item.templateStageId"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="2" style="padding: 0;">
                                    <a-space :size="8">
                                        <a-button
                                            style="margin-left: 0;padding: 0"
                                            type="link"
                                            class="template-delete"
                                            @click="handleDeleteStage(index, item)"
                                            size="small"
                                            >删除
                                        </a-button>
                                        <a-button
                                            style="margin-left: 0;padding: 0"
                                            type="link"
                                            class="template-delete"
                                            @click="handleExpend(index, item)"
                                            size="small"
                                            >{{ item.isShow ? '折叠' : '展开' }}
                                        </a-button>
                                    </a-space>
                                </a-col>
                                <a-form-item :name="['templateStageList', index, 'templateStageId']">
                                    <a-input
                                        v-model:value="item.templateStageId"
                                        :maxlength="20"
                                        disabled
                                        type="hidden"
                                    />
                                </a-form-item>
                                <template v-if="item.isShow">
                                    <a-col :span="22">
                                        <a-form-item
                                            label="目标"
                                            :name="['templateStageList', index, 'mubiao']"
                                            :rules="state.stageRules.mubiao"
                                        >
                                            <a-textarea
                                                v-model:value="item.mubiao"
                                                placeholder="请输入"
                                                :rows="1"
                                                :maxlength="20"
                                            />
                                        </a-form-item>
                                    </a-col>
                                    <a-col :span="22">
                                        <a-form-item
                                            label="关键路径"
                                            :name="['templateStageList', index, 'guanjianlujing']"
                                            :rules="state.stageRules.guanjianlujing"
                                        >
                                            <a-textarea
                                                v-model:value="item.guanjianlujing"
                                                placeholder="请输入"
                                                :rows="1"
                                                :maxlength="20"
                                            />
                                        </a-form-item>
                                    </a-col>
                                    <a-col :span="22">
                                        <a-form-item
                                            label="甲方主要角色"
                                            :name="['templateStageList', index, 'jiafangjuese']"
                                            :rules="state.stageRules.guanjianlujing"
                                        >
                                            <a-textarea
                                                v-model:value="item.jiafangjuese"
                                                placeholder="请输入"
                                                :rows="1"
                                                :maxlength="20"
                                            />
                                        </a-form-item>
                                    </a-col>
                                    <a-col :span="22">
                                        <a-form-item
                                            label="甲方责任及配合事项"
                                            :name="['templateStageList', index, 'jiafangshixiang']"
                                            :rules="state.stageRules.jiafangshixiang"
                                        >
                                            <a-textarea
                                                v-model:value="item.jiafangshixiang"
                                                placeholder="请输入"
                                                :rows="1"
                                                :maxlength="20"
                                            />
                                        </a-form-item>
                                    </a-col>
                                    <a-col :span="22">
                                        <a-form-item
                                            label="阶段权重"
                                            :name="['templateStageList', index, 'jieduanquanzhong']"
                                            :rules="state.stageRules.jieduanquanzhong"
                                        >
                                            <a-input-number
                                                style="width: 100%"
                                                v-model:value="item.jieduanquanzhong"
                                                placeholder="请输入(支持小数点后一位的整数数字)"
                                            />
                                        </a-form-item>
                                    </a-col>
                                    <a-divider
                                        style="
                                            margin: 0;
                                            margin-bottom: 15px;
                                            background-color: rgba(56, 117, 255, 0.5);
                                        "
                                    />
                                    <template v-for="(roleItem, roleIndex) in item.jieduanjuese" :key="roleIndex">
                                        <a-col :span="11">
                                            <a-form-item
                                                label="阶段角色"
                                                :name="['templateStageList', index, 'jieduanjuese', roleIndex, 'role']"
                                                :rules="state.stageRules.role"
                                            >
                                                <a-select
                                                    v-model:value="roleItem.role"
                                                    placeholder="请选择"
                                                    @focus="getRolePeople"
                                                    :options="directorRoleList"
                                                />
                                            </a-form-item>
                                        </a-col>
                                        <a-col :span="11">
                                            <a-form-item
                                                label="权重(相加=100%)"
                                                :name="[
                                                    'templateStageList',
                                                    index,
                                                    'jieduanjuese',
                                                    roleIndex,
                                                    'juesequanzhong'
                                                ]"
                                                :rules="state.stageRules.juesequanzhong"
                                            >
                                                <a-input-number
                                                    style="width: 100%"
                                                    v-model:value="roleItem.juesequanzhong"
                                                    placeholder="请输入"
                                                />
                                            </a-form-item>
                                        </a-col>
                                        <a-col :span="2" style="padding: 0">
                                            <a-space :size="8" style="position: relative;top: 10px">
                                                <div class="add-btn" @click="handleAddStageJdRule(index, '下方')"></div>
                                                <div
                                                    class="del"
                                                    @click="handleDeleteStageJdRule(index, roleIndex)"
                                                ></div>
                                            </a-space>
                                        </a-col>
                                    </template>
                                </template>
                            </a-row>
                            <a-divider style="margin: 0; margin-bottom: 15px; background-color: #d9d9d9" />
                        </div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

屎山制造者2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值