业务需求:根据接口提供的数据动态生成对应的输入框超A,A,B,C,D,E,并且可手动添加,删除行操作。 页面渲染如下:
<div class="authroles_row" v-for="(item, index) in formValidate.saveRoleUserDTOS" :key="index"> <Row v-if="rowDis"> <Col span="4"> <FormItem label="月份:" :prop="'saveRoleUserDTOS.' + index + '.months'" ref="monthSelect" :rules="ruleValidate.months" > <Select v-model="item.months" @on-select="val => handleChangeType(val, index)" style="width: 100%" clearable :disabled="item.inputDis" > <Option :value="item.value" :label="item.label" :key="item.value" v-for="item in monthList" :disabled="item.dis" >{{ item.value }}月</Option > </Select> </FormItem> </Col> <Col span="4" v-for="(i, k) in item.amounts" :key="k"> <FormItem :label="i.key + ':'" :rules="{ required: true, message: '每月签赠游戏币额度不允许为空', trigger: 'blur', type: 'number' }" :prop="'saveRoleUserDTOS.' + index + '.amounts.' + k + '.value'" > <Input v-model.number="item.amounts[k].value" v-filterinput="{ reg: regExp.nan }" placeholder="请输入1~999999之间" :maxlength="6" :disabled="item.inputDis" @on-blur="val => filterVal(val, index, k)" > </Input> </FormItem> </Col> </Row> <Poptip confirm transfer title="你确定要删除吗?" @on-ok="removeItem(index)"> <Icon type="md-trash" size="24" color="#808695" class="removeicon" v-show="!item.btnDis && index !== 0" /> </Poptip> <Icon type="ios-add-circle" size="24" color="#2D8CF0" v-show="index === formValidate.saveRoleUserDTOS.length - 1 && formValidate.saveRoleUserDTOS.length < 12" class="addicon" :class="{ isone: formValidate.saveRoleUserDTOS.length === 1 }" @click="addItem" /> </div>
场景一、当选择年份的时候会从接口获取Array数据saveRoleUserDTOS。因为select校验方式'change'的缘故,当切换年份的时候会一直触发select月份的校验(若切换年份获取Data为空时页面会有红框校验报错)。
解决方案:给年份绑定自定义校验函数
:rules="ruleValidate.months",定义一个布尔值monthStatus来校验月份必填项,当年份改变的时候monthStatus为false,当点击表单提交按钮的时候monthStatus为true。
ruleValidate: { roles: { required: true, message: '请选择授权角色名称', trigger: 'change', type: 'array' }, year: [{ required: true, message: '请选择年份', trigger: 'change', type: 'number' }], months: [ { required: true, trigger: 'change', validator: (rule, value, callback) => { if ((value === undefined || value === '') && this.monthStatus) { callback(new Error('月份不允许为空')) } else { callback() } } } ] }
场景二、当切换年份获取接口数据为空的时候,此时页面只有默认一行输入框,对输入框blur触发非空校验后切换下一个年份,因为diff算法的原理,页面的校验展示会依然存在。
解决方案:定义布尔值rowDis,使用v-if配合setTimeout处理,当切换年份的时候对Row进行隐藏,成功获取到Array数据后展示。
if (res.data.status === 200) { let _this = this setTimeout(() => { _this.rowDis = true }, 10) if (res.data.data.length === 0) { this.formValidate.saveRoleUserDTOS = [ { months: '', amounts: this.defaultAmounts(this.shopLevelArr) } ] this.$set(this.formValidate.saveRoleUserDTOS) } .... }
嗯,就酱紫~