第一种:
<template>
<div>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item v-for="item in formList" :label="item.name" :key="item.id" :prop="item.prop">
<el-input v-model="form[item.prop]" style="width:500px"></el-input><i class="el-icon-circle-plus-outline" @click="add()"></i>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data(){
return {
//模拟后台list
list:[
{id:'001',name:'输入框1'},
{id:'002',name:'输入框2'}
],
formList:[],
form:{},
rules:{}
}
},
created(){
this.getData()
},
methods:{
getData(){
this.formList = this.list.map((item)=>{
item.prop = 'name'+item.id
this.$set(this.form,item.prop,'')
return item
})
this.formList.map((item)=>{
let getRules = []
const validator = (rule,value,callback)=>{
const reg = new RegExp(/^[A-Za-z][A-Za-z0-9-]*$/)
if (!reg.test(value)) {
return callback(
new Error("字母开头,并且只包含字母数字和中划线")
);
}
}
getRules.push({validator:validator,trigger: "blur"})
this.rules[item.prop]=getRules
})
console.log("this.rules",this.rules)
},
add(){
let id = '000'+this.list.length //简易模拟一下id,可以随机生成id
this.list.push({id:id,name:'输入框'})
this.getData()
}
}
}
</script>
第二种,仿照el-form官网写法:
<template>
<div>
<el-form
ref="form"
:model="form"
label-width="50px"
label-position="left"
>
<div v-for="(item, index) in form.infoList" :key="item.id" class="itemSty">
<el-form-item label="名称" style="width:200px;" >
<el-select
v-model="item.name"
placeholder="请选择"
>
<el-option
v-for="item in options"
:key="item.key"
:label="item.label"
:value="item.value"/>
</el-select>
</el-form-item>
<el-form-item label="级别" style="width:200px;">
<el-input
v-model="item.count">
</el-input>
</el-form-item>
<el-form-item label="地址"
style="width:200px;"
:prop="'infoList.' + index + '.path'"
:rules="[
{ required: true, message: '请输入地址', trigger: 'blur' },
{validator:item.validator,message: '请输入正确地址', trigger: ['blur','change']}
]"
>
<el-input
:style="{width: '280px'}"
v-model="item.path">
</el-input>
</el-form-item>
<el-form-item :style="{ width: '300px' }">
<el-button @click="addItem">增加</el-button>
<el-button @click="removeDataItem($event, index)">删除</el-button>
</el-form-item>
</div>
</el-form>
</div>
</template>
<script>
export default {
data(){
const pathValidator = (rule,value,callback)=>{
const reg = new RegExp(/^[A-Za-z][A-Za-z0-9-]*$/)
if (!reg.test(value)) {
return callback(
new Error("字母开头,并且只包含字母数字和中划线")
)
}
}
return {
form:{
infoList: [
{
id:'path'+Date.now(),
path:"",
name:'',
count:'',
validator:pathValidator,
}
],
},
options:[
{ key:'key1',value:'001',label:'下拉数据1'},
{ key:'key2',value:'002',label:'下拉数据2'},
]
}
},
methods:{
addItem(){
this.form.infoList.push({
id:'path'+Date.now(),
path:"",
name:'',
count:'',
validator:this.pathValidator,
});
},
removeDataItem(item, index){
this.form.infoList = this.form.infoList.filter((item, i) => {
return i !== index;
})
},
}
}
</script>
<style scoped>
.itemSty{
width:800px;
height:100px;
display: flex;
justify-content: space-between;
}
</style>
附加:
添加多组选项时,选择过名称后,再次添加,点击名称下拉菜单不会出现选过的数据;
过滤调已选的下拉数据,只展示剩余可选的。
<template>
<div>
<el-form
ref="form"
:model="form"
label-width="50px"
label-position="left"
>
<div v-for="(item, index) in form.infoList" :key="item.id" class="itemSty">
<el-form-item label="名称" style="width:300px;margin-right:15px" >
<el-select
v-model="item.name"
placeholder="请选择"
@change="changeName($event,item)"
>
<el-option
v-for="item in options"
:key="item.key"
:label="item.label"
:value="item.value"/>
</el-select>
</el-form-item>
<el-form-item label="级别" style="width:200px;margin-right:15px">
<el-input
v-model="item.count">
</el-input>
</el-form-item>
<el-form-item label="地址" style="width:400px;margin-right:15px"
:prop="'infoList.' + index + '.path'"
:rules="[
{ required: true, message: '请输入地址', trigger: 'blur' },
{validator:item.validator,message: '请输入正确地址', trigger: ['blur','change']}
]"
>
<el-input
:style="{width: '280px'}"
v-model="item.path">
</el-input>
</el-form-item>
<el-form-item style="width:500px;margin-left:15px">
<el-button @click="addItem">增加</el-button>
<el-button @click="removeItem($event, index,item)">删除</el-button>
</el-form-item>
</div>
</el-form>
</div>
</template>
<script>
export default {
data(){
const pathValidator = (rule,value,callback)=>{
const reg = new RegExp(/^[A-Za-z][A-Za-z0-9-]*$/)
if (!reg.test(value)) {
return callback(
new Error("字母开头,并且只包含字母数字和中划线")
)
}
}
return {
list:[
{id:'001',type:'work',name:'输入框1'},
{id:'002',type:'work',name:'输入框2'},
{id:'003',type:'data',name:'输入框3'},
{id:'004',type:'data',name:'输入框4'},
{id:'005',type:'data',name:'输入框5'}
],
form:{
infoList: [
{
id:'path'+Date.now(),
path:"",
name:'',
count:'',
validator:pathValidator,
}
],
},
optionsAll:[
{ key:'key1',type:'work',value:'001',label:'下拉数据1'},
{ key:'key2',type:'work',value:'002',label:'下拉数据2'},
{ key:'key3',type:'data',value:'003',label:'下拉数据3'},
{ key:'key4',type:'data',value:'004',label:'下拉数据4'},
{ key:'key5',type:'data',value:'005',label:'下拉数据5'},
{ key:'key6',type:'data',value:'006',label:'下拉数据6'},
],
options:[],
optionsUsed:[]
}
},
created(){
this.initOpt()
},
methods:{
initOpt(){
this.options = this.optionsAll
},
//选择事件
changeName(val,item){
this.filterItem()
},
filterItem(){
//得到已用
this.optionsUsed = this.form.infoList.map((listItem)=>{
return listItem
})
this.options = this.optionsAll
//根据已用过滤全部数据,得到可用
this.optionsUsed.map((item)=>{
this.options= this.options.filter((i)=>{
return item.name!==i.value
})
})
},
addItem(){
this.form.infoList.push({
id:'path'+Date.now(),
path:"",
name:'',
count:'',
validator:this.pathValidator,
});
},
removeItem(e, index, item){
this.form.infoList = this.form.infoList.filter((item, i) => {
return i !== index;
})
this.filterItem()
},
}
}
</script>
<style scoped>
.itemSty{
height:40px;
margin: 15px 0;
display: flex;
justify-content: space-between;
}
</style>