需求及下图展示的那样,红框里是一组,通过点击右下角的添加按钮可以生成一组新的,除了第一组不能删除,后来添加的每组都可以删除,每组里面的上传视频和视频链接,二者至少有一个有值,红色星号标识为必填项。
正常的填写逻辑应该如下图(注意视频的字段星号的变化)
html代码实现:
因为每组里面的每个输入框都是循环出来的,然后每一组又是动态生成的,又是一个大循环,涉及到循环嵌套,所以html部分如下:
<el-form :model="editImgFrom" :rules="editRules" ref="videoFromRef" label-width="108px">
<div v-for="(item, index) in editImgFrom.tableData" :key="index">
<div class="editWriter-writerArray">
<el-form-item label="产品:" :prop="'tableData.'+ index +'.relatedProduct'" :rules="editRules.relatedProduct">
<el-select v-model="item.relatedProduct" clearable>
<el-option
v-for="item in editProduct"
:key = 'item.code'
:value = "item.code"
:label = "item.name"/>
</el-select>
</el-form-item>
<el-form-item class="input_240" label="所属脚本:" :prop="'tableData.'+ index +'.state'" :rules="editRules.relatedScript">
<el-autocomplete
v-model="item.state"
:fetch-suggestions="(queryString,callback)=>{querySearchAsync(queryString, callback, index)}"
placeholder="请输入内容"
@select="(value)=>handleSelect(value, index)"
></el-autocomplete>
</el-form-item>
<el-form-item label="投放媒体:" :prop="'tableData.'+ index +'.placeMedia'" :rules="editRules.placeMedia">
<el-checkbox-group v-model="item.checkedId" @change="checkedChange(index, item.checkedId)">
<el-checkbox label="1">快手</el-checkbox>
<el-checkbox label="2">腾讯</el-checkbox>
<el-checkbox label="3">头条</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="上传视频:" :prop="'tableData.'+index+'.content'" :rules="editRules.content" :required="!item.externalVideoLinks">
<el-button @click="openVideoDialog(index)" v-if="!item.content">上传视频</el-button>
<video v-else :src="`${BASEURL}${item.content}`" class="avatar" controls="controls">您的浏览器不支持视频播放</video>
<el-button v-if="item.content" @click="openVideoDialog(index)" type="text">替换视频</el-button>
</el-form-item>
<el-form-item label="视频链接:" :prop="'tableData.'+ index +'.externalVideoLinks'" :rules="editRules.externalVideoLinks" :required="!item.content">
<el-input v-model="item.externalVideoLinks" clearable :maxlength='200'/>
</el-form-item>
<el-button type="primary" class="del_btn" style="margin-left:110px;" @click="delCurrentRow(index)" v-show="index>0">删除</el-button>
</div>
</div>
<div class="editWriter-tabButtom">
<el-button @click="addRows">添加</el-button>
</div>
</el-form>
</div>
<div class="editWriter-footer">
<el-button @click="submitClick">保存</el-button>
</div>
注意**:prop="'tableData.'+ index +'.externalVideoLinks'"
和:required="!item.content"
**的写法。
js部分:
data(){
const _this=this;
let validvideo=(rule,value,callback)=>{
let newArr=rule.field.split('.')
let currentIndex=newArr[1];
let currentProp=newArr[2];
let currentPropBro='';
if(currentProp==='externalVideoLinks'){
currentPropBro=this.editImgFrom.tableData[currentIndex].content;
}else{
currentPropBro=this.editImgFrom.tableData[currentIndex].externalVideoLinks;
}
if(value===''&¤tPropBro===''){
callback(new Error('请上传视频或输入视频链接'))
}else{
_this.$refs['videoFromRef'].clearValidate('tableData.'+ currentIndex + '.externalVideoLinks');
_this.$refs['videoFromRef'].clearValidate('tableData.'+ currentIndex + '.content');
callback()
}
};
return {
editImgFrom: {
tableData: [
{
content: '', //视频url
relatedScript: '', //关联脚本id
relatedProduct: '', //关联产品id
placeMedia: '', //投放媒体,逗号分割(1:快手,2:腾讯,3:头条)
userId: '', //用户id
checkedId: [],
externalVideoLinks:'',//视频链接
}
]
},
editRules: {
relatedProduct: [{required: true, message: '请选择产品', trigger: 'change'}],
placeMedia: [{required: true, message: '请选择投放媒体', trigger: 'change'}],
content: [{validator:validvideo,message: '请上传视频', trigger:['change','blur']}],
externalVideoLinks: [{validator:validvideo,message: '请输入视频链接', trigger:['change','blur']}],
},
editProduct:[],
scriptInputList: [],
}
},
methods:{
submitClick(handleType){
let vm = this;
vm.$refs['videoFromRef'].validate((valid)=>{
if(valid){
//此处写验证通过后的提交逻辑
}else{
vm.$TopTip({ message: '存在必填项未填写' });
return false;
}
})
},
}
注意在rules里不要写required:true,data方法里自定义验证规则时,当一方有值,要记得清除验证。否则可能会出现英文提示或者输入完之后再删除提示语残留的问题。