el-form动态表单的两种写法,过滤下拉选择

第一种:

​
<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>

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值