<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>