element-ui表单循环渲染+字段单独校验

573 阅读2分钟

适用场景

vue中使用element-ui, form组件,列表渲染数据,并做到每个字段单独校验

数据示例: 用到的函数为接口或处理数据函数,与本文无关。

 let PromiseList = arr.map((item) =>
     licenseListNum(JSON.stringify([item]))
 );
 Promise.all(PromiseList).then((res) => {
     if (res.length > 0) {
       this.restoreForm.memCertificateList = res.map((item) => {
         return {
           ...item.data,
           type: item.data.memCategory,
           memType: (() => {
             return `0${item.data.level}`;
           })(),
           typeLabel: (() => {
             return getApplyLabel(item.data.memCategory);
           })(),
           levelList: (() => {
             let List = [];
             if (getMemLevel(item.data.memCategory) == 1) {
               List = this.dict.type.waw_member_type;
             } else {
               List = this.dict.type.zax_member_type;
             }
             return List;
           })(),
         };
       });
     }
     this.$nextTick(() => {
       this.restoreVis = true;
     });
 });

处理过后数据如图,

image-20240514111612827.png

然后html的代码为

 <el-dialog
   title="恢复会员"
   :visible.sync="restoreVis"
   width="1000px"
   :before-close="closeRestoreForm"
 >
   <el-form
     :model="restoreForm"
     ref="restoreForm"
     label-width="120px"
     :rules="restoreRules"
     class="gridBox mt20"
   >
     <template v-for="(item, index) in restoreForm.memCertificateList">
       <el-form-item
         :label="`${item.typeLabel}会员级别`"
         :prop="`memCertificateList[${index}].memType`"
         :rules="restoreRules.memType"
       >
         <el-select
           v-model="item.memType"
           placeholder="请选择"
           style="width: 90%"
         >
           <el-option
             v-for="item in item.levelList"
             :key="item.value"
             :label="item.label"
             :value="item.value"
           >
           </el-option>
         </el-select>
       </el-form-item>
       <el-form-item
         :label="`${item.typeLabel}证书编号`"
         :prop="`memCertificateList[${index}].certificateNum`"
         :rules="restoreRules.certificateNum"
       >
         <el-input
           style="width: 90%"
           v-model="item.certificateNum"
           placeholder="请输入内容"
         ></el-input>
       </el-form-item>
     </template>
     <el-form-item label="入会日期" prop="joinDate">
       <el-date-picker
         v-model="restoreForm.joinDate"
         type="date"
         style="width: 90%"
         placeholder="选择日期"
         :clearable="false"
         value-format="yyyy-MM-dd"
       >
       </el-date-picker>
     </el-form-item>
     <el-form-item label="证书到期时间" prop="certificateExpirTime">
       <el-date-picker
         v-model="restoreForm.certificateExpirTime"
         type="date"
         placeholder="选择日期"
         style="width: 90%"
         :clearable="false"
         value-format="yyyy-MM-dd"
       ></el-date-picker>
     </el-form-item>
     <el-form-item label="会员服务期限" prop="memServiceExpireDate">
       <el-date-picker
         v-model="restoreForm.memServiceExpireDate"
         type="date"
         placeholder="选择日期"
         style="width: 90%"
         :clearable="false"
         value-format="yyyy-MM-dd"
       ></el-date-picker>
     </el-form-item>
     <el-form-item label="备注" prop="remark">
       <el-input
         style="width: 90%"
         v-model="restoreForm.remark"
         placeholder="选择填写备注"
       ></el-input>
     </el-form-item>
   </el-form>
   <span slot="footer" class="dialog-footer">
     <el-button @click="closeRestoreForm">取 消</el-button>
     <el-button type="primary" @click="restoreFormSubmit">确 定</el-button>
   </span>
 </el-dialog>

规则为

 restoreForm: {},
 restoreRules: {
     memType: [
       { required: true, message: "请选择会员级别", trigger: "change" },
     ],
     certificateNum: [
       { required: true, message: "请输入会员编号", trigger: "blur" },
     ],
     joinDate: [
       { required: true, message: "请选择入会日期", trigger: "change" },
     ],
     certificateExpirTime: [
       { required: true, message: "请选择证书到期时间", trigger: "change" },
     ],
     memServiceExpireDate: [
       { required: true, message: "请选择会员服务期限", trigger: "change" },
     ],
     remark: [{ required: true, message: "请输入备注", trigger: "blur" }],
 },

按理来说这样就好使了,但是我遇到一个问题,就是死活不好使,而且是第一次弹窗的时候,绑定的值删不掉,以为是没有刷新, 然后加了input事件,强刷,

这次是可以删掉了,但是校验不好使。以为是没绑定key的原因,结果还是不对,后边排查下来,原来是因为页面初始化的时候没有给restoreForm赋字段,

在初始化的时候改为

 restoreForm: {
     memCertificateList: [],
     joinDate: null,
     certificateExpirTime: null,
     memServiceExpireDate: null,
     remark: null,
 },

就好了。

这就是vue2存在的一个问题,其实还有一个解决方式,可以使用this.$set来赋值,也可以解决这个问题。