思路
一、需要表格、表单、校验三个数据容器。
1、表格,只需要添加数据时,把动态key存入就行,name和age没用(可以不要)
2、表单,通过动态key拼接存入数据。方法入下
输入的input要绑定表单项,通过动态key,绑定不同的表单项,如下,input绑定方法
3、校验:每次点击新增的时都会通过key添加动态校验
form-item也要绑定动态校验(也是通过key区分)如下:
需要配置的地方
1、点击添加,添加动动态表格数据、动态表单数据、动态校验,唯一变要变化的key
2、配置动态prop与动态v-model绑定就好了
<template>
<el-dialog title="" :visible.sync="dialogVisible" width="790px" height="700px">
<div class="tr mb-16">
<el-button @click="addData">添加数据</el-button>
</div>
<el-form :model="form" :rules="rules" class="mb-24">
<el-table :data="data" stripe>
<el-table-column prop="name" label="姓名">
<template slot-scope="scope">
<el-form-item label="" :prop="'name'+'-'+scope.row.key">
<el-input v-model="form['name'+'-'+scope.row.key]"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="age" label="年龄">
<template slot-scope="scope">
<el-form-item label="" :prop="'age'+'-'+scope.row.key">
<el-input v-model="form['age'+'-'+scope.row.key]"></el-input>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form>
</el-dialog>
</template>
<script>
export default {
data() {
return {
dialogVisible:false,
data: [], //表格数据
form: {},//表单数据
rules: {},//校验数据
key:0,//因为数据都是添加的,需要一个key区分
}
},
methods:{
//打开弹框
open(){
this.dialogVisible=true
},
// 点击添加数据
addData(){
this.key++
// 给表格添加数据
this.data.push({key:this.key})
// 给表单添加数据(用来绑定input的v-model)----重点1----
// 1、添加姓名输入框绑定的对象(应为有key不一样,所以不会覆盖)
this.$set(this.form,'name'+'-'+this.key,'')
// 2、添加年龄输入框绑定的对象
this.$set(this.form,'age'+'-'+this.key,'')
// 动态添加校验(每次新增时,添加校验)------重点2-------
this.$set(this.rules,'name'+'-'+this.key,[ { validator: this.validatePass, trigger: 'blur' }])
this.$set(this.rules,'age'+'-'+this.key,[ { validator: this.validatePass, trigger: 'blur' }])
},
// 验证器函数
validatePass(rule, value, callback){
console.log(rule, value,'????');
let str=rule.field.split('-')[0]
if(value===''){
if(str=='name'){
callback(new Error('请输入姓名'))
}else{
callback(new Error('请输入年龄'))
}
}else{
callback()
}
}
}
}
</script>
<style lang="scss" scoped>
>>>.el-table {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400 !important;
border: 1px solid #e8eaec !important;
}
</style>
其他简洁方案
<template>
<el-dialog @open="open" title="模拟客户信息" :visible.sync="roleDialogVisable" :close-on-press-escape="false"
style="font-size: 14px;" width="960px">
<el-form :model="formRole" ref="formRole">
<!-- 循环客户信息 -->
<el-row :gutter="16" class="mb-10 border-box" v-for="(role, rindex) in formRole.roleList" :key="rindex + '-role'">
<el-col :span="11">
<el-form-item :prop="`roleList[${rindex}][name]`" :rules="[
{ required: true, message: '请输入项目', trigger: 'change,blur' }
]">
<yl-input-v2 v-model="role.name" placeholder="请输入项目" maxlength="50" :disabled="!rindex"></yl-input-v2>
</el-form-item>
</el-col>
<el-col :span="11" :offet="1">
<el-form-item :prop="`roleList[${rindex}][description]`" :rules="[
{ required: true, message: '请输入描述', trigger: 'change' }
]">
<yl-input-v2 v-model="role.description" placeholder="请输入描述" maxlength="50" />
</el-form-item>
</el-col>
<el-col :span="1" class="lh-40">
<i class="el-icon-delete fc-7D8592 cursor-pointer font-16 pos-rel" style="top: -3px;" v-show="rindex"
@click="handleDelField(role, rindex)"></i>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer flex align-item-center justify-space-between">
<div class="cursor-pointer fc-3377ff" @click="handleAddField" v-if="formRole.roleList.length < 20">
<yl-icon name="icon-jia" class="pos-rel mr-4" style="top: -1px;"></yl-icon>
增加客户信息
</div>
<div>
<el-button @click="showRoleDialog(0)">取 消</el-button>
<el-button type="primary" @click="showRoleDialog(2)">保存</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
props: {
simulatedRole: {
type: Array,
default: () => []
}
},
data() {
return {
roleDialogVisable: false,
formRole: {
roleList: [] //客户信息的项
}
}
},
methods: {
// 打开弹框
open() {
this.formRole.roleList = this.simulatedRole
},
// 增加客户信息
handleAddField() {
if (this.formRole.roleList.length < 20) { //如果小于20
this.formRole.roleList.push({ //添加一行
name: '',
description: ''
})
}
},
handleDelField(item) {
let index = this.formRole.roleList.indexOf(item)
this.formRole.roleList.splice(index, 1);
},
showRoleDialog(type) {
if(type === 2) {
this.$refs['formRole'].validate((valid) => {
if (valid) {
let newItem = []
this.formRole.roleList.map(v => {
if (v.name && v.description) {
newItem.push(v)
}
})
this.$emit('customerMessageFn',newItem)
this.roleDialogVisable = false;
} else {
return false
}
})
} else {
this.roleDialogVisable = false;
}
},
}
}
</script>
<style lang="scss" scoped>
>>>.el-dialog__body {
padding-top: 14px !important;
padding-bottom:0 !important;
}
</style>