Vue+Element一步步实现动态添加Input_输入框案例

目录
  • 输入式动态添加
  • 单选式动态添加
  • 组合式动态添加
  • 组合式动态添加(回传名称)
  • 单选、多选组合式
  • 数据回显
  • 完整示例
  • 总结
  • 单选切换多选(补充)
  • 下拉框渲染卡顿问题(补充)
  • 双循环遍历优化

输入式动态添加

输入式:即input的值由用户输入;例如:通过自定义用户标签,给用户动态添加多个标签。

<template>
<div class="app">
  <div v-for="item in table" :key="item.id">
    <el-input v-model="item.label" class="el-input"></el-input>
  </div>
 <el-button @click="addInput">添加</el-button>
 <el-button @click="search">查看</el-button>
</div>
</template>

<script>
  export default {
     data () {
    return {
      table: [
        { id: '12121', label: '' }
      ]
    }
  },
  methods: {
    // 动态添加
    addInput () {
      this.table.push({ id: Date.now(), label: '' })
    },
    // 查看
    search () {
      console.log(this.table)
    },
  }
  }
</script>

单选式动态添加

例如:给一名老师动态添加多个监考科目,后台接收科目代码(courseId)。

<div v-for="(item,index) in list" :key="item.id">
    <el-select
      class="el-select"
      v-model="item.courseId"
      placeholder="请选择"
      @change="changeSelect($event,index)">
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value">
      </el-option>
    </el-select>
</div>
 
      list: [
        { courseId: '', id: '1' }
      ],
      options: [
        { value: '123', label: '英语' },
        { value: '456', label: '数学' },
        { value: '868', label: '语文' },
        { value: '672', label: '化学' },
        { value: '684', label: '物理' }
      ],
    // 动态添加
    addInput () {
      this.list.push({ id: Date.now(), courseId: '' })
    },

组合式动态添加

例如:给学生各个科目打上分数。

 <div v-for="item in list1" :key="item.id">
    <el-select
      class="el-select"
      v-model="item.courseId"
      placeholder="请选择科目"
     >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value">
      </el-option>
    </el-select>
    <el-input v-model="item.grade" class="el-input" placeholder="请填写分数"></el-input>
  </div>
      list1: [
        { courseId: '', id: '1', grade: '' }
      ],
     options: [
        { value: '123', label: '英语' },
        { value: '456', label: '数学' },
        { value: '868', label: '语文' },
        { value: '672', label: '化学' },
        { value: '684', label: '物理' }
      ],

    addInput () {
      this.list1.push({ id: Date.now(), courseId: '', grade: '' })
    },        

      // this.list1
      // [
      //   {
      //     "courseId":"123",
      //     "id":"1",
      //     "grade":"96"
      //   },
      //   {
      //     "id":1636423648221,
      //     "courseId":"456",
      //     "grade":"100"
      //   }
      // ]

组合式动态添加(回传名称)

例如:给学生各个科目打上分数,后端需要同时接收科目名称和科目id。

// 后台接收的数据
courseList:[
    {courseId: '', grade: '', courseName: '' }
    {courseId: '', grade: '', courseName: '' }
]

这时候,只需要给el-select添加change事件,在获取id的同时获取到名称即可。

<div v-for="(item,index) in list2" :key="item.id">
    <el-select
      class="el-select"
      v-model="item.courseId"
      placeholder="请选择科目"
      @change="changeOneCourse($event,index)"
     >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value">
      </el-option>
    </el-select>
    <el-input v-model="item.grade" class="el-input" placeholder="请填写分数"></el-input>
  </div>
 changeOneCourse(val, index) {
      this.options.find((item) => {
        if (item.value === val) {
          this.list2[index]['courseName'] = item.label // 根据绑定值id获取到名称label
        }
      })
    }
      // this.list2: [
      // {
      //   "courseId":"123",
      //   "id":"1",
      //   "grade":"96",
      //   "courseName":"英语"
      // }
      // ]

单选、多选组合式

例如:给各个年级添加不同科目,后端需要同时接收【科目名称,科目id】,【年级id,年级名称】。

 gradeList:[
        { courseList: [
          { courseId: '', courseName: '' },
          { courseId: '', courseName: '' }
        ],
        gradeData: { grade: '', gradeName: ' ' }
        }
      ]
<div v-for="(item,index) in list3" :key="item.id">
  <el-select v-model="item.gradeList" placeholder="请选择年级" @change="changeGrad($event,index)">
    <el-option
      v-for="item in options1"
      :key="item.value"
      :label="item.label"
      :value="item.value">
    </el-option>
  </el-select>
  <el-select v-model="item.courseList" multiple placeholder="请选择科目" @change="changeSelect($event,index)">
  <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value">
  </el-option>
  </el-select>
</div>
 <el-button @click="addInput">添加</el-button>
 <el-button @click="search">查看</el-button>
      list3: [
         { gradeList: '', id: '1', courseList: '' }
      ],
      options: [
        { value: '123', label: '英语' },
        { value: '456', label: '数学' },
        { value: '868', label: '语文' },
        { value: '672', label: '化学' },
        { value: '684', label: '物理' }
      ],
      options1: [
        { value: '1238635', label: '一年级' },
        { value: '4568635', label: '二年级' },
        { value: '8688635', label: '三年级' },
        { value: '6728635', label: '八年级' },
        { value: '6848635', label: '九年级' }
      ],
      courseList: [], // 存放多选
      grade: [], // 存放单选
      name: [],
  methods: {
    addInput () {
      this.list3.push({ id: Date.now(), gradeList: '', courseList: '' })
    },
    search () {
      let arr3 = []
      for (let i = 0; i < this.courseList.length; i++) {
        arr3.push(Object.assign(this.courseList[i] || {}, this.grade[i] || {})) // 合并数组对象
      }
      console.log(arr3) // 输出传给后台的结构
    },
    // 处理多选的值
    changeSelect (val, index) {
      let courseList = { courseList: [] }
      this.name = []
      this.courseList[index] = courseList // 初始化第一个值
      // =====================根据变化的值赋值,有就赋值,无就删除===========================
      for (let i = 0; i <= val.length - 1; i++) {
        this.options.find((item) => {
          if (item.value === val[i]) {
            this.name.push(item.label) // 根据绑定值id获取到名称label
          }
        })
      }
      // =====================进行赋值===========================
      for (let i = 0; i <= val.length - 1; i++) {
        let obj = {}
        obj['courseId'] = val[i]
        obj['courseName'] = this.name[i]
        this.courseList[index]['courseList'].push(obj)
      }
      console.log(this.courseList) // 相当于多选课程的数据
    },
    changeGrad (val, index) {
      this.options1.find((item) => {
        if (item.value === val) {
          this.list2[index]['gradeName'] = item.label // 根据绑定值id获取到名称label
        }
      })
      let grade = { grade: { gradeName: '', gradeId: '' } }
      //
      let gradeName = ''
      this.grade[index] = grade // 初始化第一个值
      this.options1.find((item) => {
        if (item.value === val) {
          gradeName = item.label // 根据绑定值id获取到名称label
        }
      })
      // =====================进行赋值===========================
      this.grade[index]['grade']['gradeName'] = gradeName
      this.grade[index]['grade']['gradeId'] = val
      console.log(this.grade) // 相当于单选年级的数据
    }
  }

数据回显

动态添加数据之后,数据也正常提交给了后台,往往数据可能还需要编辑或修改,那就会涉及到数据的回显问题。

// 定义一个test方法,和echoData查看回显的数据是否正确
 // 数据回显
    echoData () {
      this.isChange = false
      this.arr3 = this.echoList // arr3提到data中全局保存
      let courseList = [] // 保存多选的值
      let obj = {}
      // 回显时初始化单选值(年级)
      this.grade = this.echoList.map(item => {
        return { grade: { ...item.grade } }
      })
      // 回显时初始化多选值(课程)
      for (let key in this.echoList) {
        let obj = {}
        obj['courseList'] = this.echoList[key]['courseList']
        this.courseList.push(obj)
      }
      // 1.拆分后台数据,构造年级回显
      this.options1 = this.echoList.map(item => {
        item.courseList.forEach(val => {
          courseList.push(val)
        })
        return {
          value: item.grade['id'],
          label: item.grade['gradeName']
        }
      })
      // 数组对象去重
      courseList = courseList.reduce((a, b) => {
        obj[b.id] ? '' : obj[b.id] = true && a.push(b)
        return a
      }, [])
      // 2.拆分后台数据,构造科目回显
      this.options = courseList.map(item => {
        return {
          value: item.id,
          label: item.courseName
        }
      })
      // 3.拆分后台数据,构造动态绑定的数据回显
      this.list3 = this.echoList.map(item => {
        let course = []
        item.courseList.forEach(val => {
          course.push(val.id)
        })
        return {
          gradeList: item.grade['id'],
          courseList: course
        }
      })
      console.log(this.arr3)
    },
   // 用于检查回显数据的赋值是否正确
    test () {
      this.courseList = []
      this.grade = []
      // 回显时初始化单选值(年级)
      this.grade = this.echoList.map(item => {
        return { grade: { ...item.grade } }
      })
      // 回显时初始化多选值(课程)
      for (let key in this.echoList) {
        let obj = {}
        obj['courseList'] = this.echoList[key]['courseList']
        this.courseList.push(obj)
      }
      console.log(this.grade)
      console.log(this.courseList)
    }

完整示例

这里暂时不对代码进行优化处理。

<template>
<div class="app">
  <!--// 输入式-->
  <!--<div v-for="item in table" :key="item.id">-->
    <!--<el-input v-model="item.label" class="el-input"></el-input>-->
  <!--</div>-->
  <!--单选式-->
<!--  <div v-for="item in list" :key="item.id">
  <el-select
    class="el-select"
    v-model="item.courseId"
    placeholder="请选择">
    <el-option
      v-for="item in options"
      :key="item.value"
      :label="item.label"
      :value="item.value">
    </el-option>
  </el-select>
  <el-input v-model="item.grade" class="el-input"></el-input>
</div>-->
  <!--组合式-->
<!--  <div v-for="item in list2" :key="item.id">
    <el-select
      class="el-select"
      v-model="item.courseId"
      placeholder="请选择科目"
     >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value">
      </el-option>
    </el-select>
    <el-input v-model="item.grade" class="el-input" placeholder="请填写分数"></el-input>
  </div>-->
  <!--组合式(回显名称)-->
<!--  <div v-for="(item,index) in list2" :key="item.id">
    <el-select
      class="el-select"
      v-model="item.courseId"
      placeholder="请选择科目"
      @change="changeOneCourse($event,index)"
    >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value">
      </el-option>
    </el-select>
    <el-input v-model="item.grade" class="el-input" placeholder="请填写分数"></el-input>
  </div>-->
  <!--单选、多选组合式-->
<div v-for="(item,index) in list3" :key="item.id">
  <el-select v-model="item.gradeList" placeholder="请选择年级" @change="changeGrad($event,index)">
    <el-option
      v-for="item in options1"
      :key="item.value"
      :label="item.label"
      :value="item.value">
    </el-option>
  </el-select>
  <el-select v-model="item.courseList" multiple placeholder="请选择科目" @change="changeSelect($event,index)">
  <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value">
  </el-option>
  </el-select>
</div>
 <el-button @click="addInput">添加</el-button>
 <el-button @click="search">查看</el-button>
 <el-button @click="echoData">回显</el-button>
 <el-button @click="test">测试</el-button>
</div>
</template>

<script>

export default {
  name: 'teacher',
  data () {
    return {
      value1: [],
      table: [
        { id: '12121', label: '' }
      ],
      list: [
        { courseId: '', id: '1' }
      ],
      list1: [
        { courseId: '', id: '1', grade: '' }
      ],
      list2: [
        { courseId: '', id: '1', grade: '', courseName: '' }
      ],
      list3: [
        { gradeList: '', id: '1', courseList: '' }
      ],
      options: [
        { value: '123', label: '英语' },
        { value: '456', label: '数学' },
        { value: '868', label: '语文' },
        { value: '672', label: '化学' },
        { value: '684', label: '物理' }
      ],
      options1: [
        { value: '1238635', label: '一年级' },
        { value: '4568635', label: '二年级' },
        { value: '8688635', label: '三年级' },
        { value: '6728635', label: '八年级' },
        { value: '6848635', label: '九年级' }
      ],
      courseList: [], // 存放多选
      grade: [], // 存放单选
      name: [],
      gradeList: [], // 分数列表
      echoList: [
        {
          'id': '55cca14cad60430191c0c3840a63b50c',
          'grade': {
            'id': 'd3d16e7edcbb4c1fb09759725c956dd4',
            'gradeName': '二年级'
          },
          'courseList': [
            {
              'id': '1455377986034917378',
              'courseName': '地理'
            },
            {
              'id': '1455377934050713601',
              'courseName': '数学'
            }
          ]
        },
        {
          'id': '55cca14cad60430191c0c3840a63b50c',
          'grade': {
            'id': 'fe3c385ab7c745a692f2c4b32c0cb2a0',
            'gradeName': '八年级'
          },
          'courseList': [
            {
              'id': '1455377934050713601',
              'courseName': '数学'
            },
            {
              'id': '1455377958553837569',
              'courseName': '历史'
            }
          ]
        }
      ],
      isChange: false,
      arr3: []
    }
  },
  methods: {
    addInput () {
      this.table.push({ id: Date.now(), label: '' })
      this.list.push({ id: Date.now(), courseId: '' })
      this.list1.push({ id: Date.now(), courseId: '', grade: '' })
      this.list2.push({ id: Date.now(), courseId: '', grade: '', courseName: '' })
      this.list3.push({ id: Date.now(), gradeList: '', courseList: '' })
    },
    search () {
      // 根据isChange判断数据是否发生变化,如果没发生变化arr3则为后台返回的数据,说明页面未发生变化
      if (this.isChange) {
        this.arr3 = []
        for (let i = 0; i < this.courseList.length; i++) {
          this.arr3.push(Object.assign(this.courseList[i] || {}, this.grade[i] || {})) // 合并数组对象
        }
      }

      console.log(this.arr3) // 输出传给后台的结构
    },
    // 处理多选的值
    changeSelect (val, index) {
      this.isChange = true
      let courseList = { courseList: [] }
      this.name = []
      this.courseList[index] = courseList // 初始化第一个值
      // =====================根据变化的值赋值,有就赋值,无就删除===========================
      for (let i = 0; i <= val.length - 1; i++) {
        this.options.find((item) => {
          if (item.value === val[i]) {
            this.name.push(item.label) // 根据绑定值id获取到名称label
          }
        })
      }
      // =====================进行赋值===========================
      for (let i = 0; i <= val.length - 1; i++) {
        let obj = {}
        obj['courseId'] = val[i]
        obj['courseName'] = this.name[i]
        this.courseList[index]['courseList'].push(obj)
      }
      console.log(this.courseList) // 相当于多选课程的数据
    },
    // 处理单选的值
    // changeOneCourse (val, index) {
    //   this.options.find((item) => {
    //     if (item.value === val) {
    //       this.list2[index]['courseName'] = item.label // 根据绑定值id获取到名称label
    //     }
    //   })
    // },
    changeGrad (val, index) {
      this.isChange = true
      // this.options1.find((item) => {
      //   if (item.value === val) {
      //     this.list2[index]['gradeName'] = item.label // 根据绑定值id获取到名称label
      //   }
      // })
      let grade = { grade: { gradeName: '', gradeId: '' } }
      let gradeName = ''
      this.grade[index] = grade // 初始化第一个值
      this.options1.find((item) => {
        if (item.value === val) {
          gradeName = item.label // 根据绑定值id获取到名称label
        }
      })
      // =====================进行赋值===========================
      this.grade[index]['grade']['gradeName'] = gradeName
      this.grade[index]['grade']['gradeId'] = val
      console.log(this.grade) // 相当于单选年级的数据
    },
    // 数据回显
    echoData () {
      this.isChange = false
      this.arr3 = this.echoList // arr3提到data中全局保存
      let courseList = [] // 保存多选的值
      let obj = {}
      // 回显时初始化单选值(年级)
      this.grade = this.echoList.map(item => {
        return { grade: { ...item.grade } }
      })
      // 回显时初始化多选值(课程)
      for (let key in this.echoList) {
        let obj = {}
        obj['courseList'] = this.echoList[key]['courseList']
        this.courseList.push(obj)
      }
      // 1.拆分后台数据,构造年级回显
      this.options1 = this.echoList.map(item => {
        item.courseList.forEach(val => {
          courseList.push(val)
        })
        return {
          value: item.grade['id'],
          label: item.grade['gradeName']
        }
      })
      // 数组对象去重
      courseList = courseList.reduce((a, b) => {
        obj[b.id] ? '' : obj[b.id] = true && a.push(b)
        return a
      }, [])
      // 2.拆分后台数据,构造科目回显
      this.options = courseList.map(item => {
        return {
          value: item.id,
          label: item.courseName
        }
      })
      // 3.拆分后台数据,构造动态绑定的数据回显
      this.list3 = this.echoList.map(item => {
        let course = []
        item.courseList.forEach(val => {
          course.push(val.id)
        })
        return {
          gradeList: item.grade['id'],
          courseList: course
        }
      })
      console.log(this.arr3)
    },
    test () {
      this.courseList = []
      this.grade = []
      // 回显时初始化单选值(年级)
      this.grade = this.echoList.map(item => {
        return { grade: { ...item.grade } }
      })
      // 回显时初始化多选值(课程)
      for (let key in this.echoList) {
        let obj = {}
        obj['courseList'] = this.echoList[key]['courseList']
        this.courseList.push(obj)
      }
      console.log(this.grade)
      console.log(this.courseList)
    }
  }
}
</script>

<style lang="scss" scoped>
  .app{
    margin: 50px auto;
    width: 500px;
  }
.el-input{
  margin-bottom: 20px;
  width: 200px;
}
  .el-select{
    margin-bottom: 20px;
    margin-right: 10px;
  }
</style>

总结

1、动态添加Input,需要密切关注页面和后台数据的处理,简单的直接绑定v-for的item,复杂的需要根据具体需求,进行调整;

2、获取id的同时利用find()获取名称;

3、纯数组合与数组对象之间的转换、合并,利用循环合自定义obj={}保存对象,并循环输出;

4、数组对象的合并,利用Object.assign(),先合并对象;

5、同时获取名称和id需要在change方法里面,同时进行,根据有值就添加,无值就删除原理;

6、数据回显,要保证数据跟动态添加时的绑定值一致 。

单选切换多选(补充)

当输入框根据条件,既可以单选,又可以多选时,会出现切换模式时,无法清除数据的问题。

 <div class="select">
      <el-select v-model="grade" placeholder="请选择年级" clearable @change="changeGrade">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"/>
      </el-select>
      <el-select v-if="isShowSelect" v-model="course" placeholder="请选择课程" clearable :multiple="isMultiple === '1'">
        <el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"
        />
      </el-select>

<script>
    data () {
    return {
      isMultiple: '0',
      isShowSelect: true,
      isShow: false,
      course: '',
      grade: '',
      options: [
        { value: '1238635', label: '一年级', isMultiple: '0' },
        { value: '4568635', label: '二年级', isMultiple: '0' },
        { value: '8688635', label: '三年级', isMultiple: '1' },
        { value: '6728635', label: '八年级', isMultiple: '1' },
        { value: '6848635', label: '九年级', isMultiple: '1' }
      ],
      options1: [
        { value: '123', label: '英语' },
        { value: '456', label: '数学' },
        { value: '868', label: '语文' },
        { value: '672', label: '化学' },
        { value: '684', label: '物理' }
      ]
    }
  },
 methods: {
      if (val) {
        // 改变年级时,判断是否可多选
        this.isMultiple = this.options.find(item => item.value === val).isMultiple
       // 多选时,绑定的是数组,单选绑定的是字符串,出现问题的地方可能是这里
        this.isMultiple === '1' ? this.course = [] : this.course = ''
      }
}
</script> 

可能是切换模式时,需要重新 v-model,但容器又没有重新渲染导致,因此可以在切换的时候,让容器重新渲染,重新 v-model ,首先给选择课程添加 v-if,,然后观察 isMultiple 的变化,变化时,让课程容器重新渲染即可。

 watch: {
    isMultiple (val) {
      if (val) {
        this.isShowSelect = false
        setTimeout(() => {
          this.isShowSelect = true
        })
      }
    }
  },

下拉框渲染卡顿问题(补充)

当渲染的数据量很大时,一次性渲染,会造成页面卡顿,甚至内存溢出现象,一次性渲染超过2000条数据的下拉框,就会出现卡顿现象(小编自测的结果,不一定准确)。解决的方法是:分页,同时支持搜索,那就可以使用 Element 的 Cascader 级联选择器。

          <el-cascader
            filterable
            ref="cascader"
            :options="options"
            :key="dialogData.pushType"
            :disabled="!(dialogData.pushType)"
            :props="optionsProps"
            :placeholder="optionsValue.length>0?optionsValue.map(item=>{return item.label}).join(','):placeholder"
            :show-all-levels="false"
            @change="changeOptionValue"
            v-model="optionsValue"
            size="mini">
          </el-cascader>

        <el-pagination
          v-if="managersTotal > 1000 && dialogData.pushType === '03'"
          @current-change="managersCurrentChange"
          :page-size="1000"
          layout="total, prev, pager, next"
          :total="managersTotal">
        </el-pagination>

既然多数据,那必然需要支持多选。

分页下的多选,在点击下一页的时候,会把上一页选择的数据清空,怎么办呢?

那就把在上页中选择的数据,保存起来,在下一页中,加入渲染中去即可。

 // @change 中保存选择的数据
 changeOptionValue (val) {
      this.saveOptionsValue = val; // 保存选择的数据
  },

 // 在点击下一页时,把上一页选择的数据 push 到渲染中去
 managersCurrentChange (val) {
      const hash = {};
     // 每次点击时,把重复数据过滤掉,不然点击一次,就会 push 一次重复数据
      this.pushOptionsList = this.saveOptionsValue.reduce(function (prev, cur) {
        !hash[cur.value] ? hash[cur.value] = prev.push({ label: cur.label, value: { value: cur.value, label: cur.label } }) : '';
        return prev;
      }, []);
      this.optionsValue = this.saveOptionsValue;
      this.managersPageNo = val;
      this.renderData(); // 接口调用,渲染数据
    },
renderData(){
 .......
 // 把上一页选择的数据,加到数组最前面
  this.pushOptionsList.length !== 0 && this.List.unshift(...this.pushOptionsList);
}

最后,在数据渲染时,要给一个渲染中的提示,最好是全局的,同时禁止用户其他的操作。毕竟数据量多,渲染需要一定的时间,这段时间不能被其他操作影响。

 openFullScreen2() {
        const loading = this.$loading({
          lock: true,
          text: 'Loading',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });
        setTimeout(() => {
          loading.close();
        }, 2000);
      }

当然分页是不太符合页面操作逻辑的,数据多的时候,应该满足模糊搜索,而不是一页页去查,再进行搜索。 查这一步,明显多余,那一步到位的做法是什么呢?element的Select选择器就给我们提供了,远程搜索的功能

<el-select
  :size="isType? 'medium':'mini'"
  v-model="optionsValue"
  multiple
  filterable
  remote
  reserve-keyword
  placeholder="请输入姓名进行搜索"
  :remote-method="remoteMethod"
  loading-text="搜索中..."
  :loading="loading">
<el-option
  v-for="item in options"
  :key="item.value"
  :label="item.label"
  :value="item.value">
</el-option>
</el-select>

<script>
 // 远程搜索
    remoteMethod (query) {
      if (query !== '') {
        setTimeout(() => {
         // 调用接口,模糊查询
        }, 200);
      } else {
        this.managersList = [];
      }
    },
</script>

注意:当el-select开启多选的时候,size最好是medium以上,不然,有时候会发生页面抖动现象

双循环遍历优化

在拆分后台数据,构造年级回显时,用到了下面所示代码

可以看到使用map()和forEach循环遍历数据,这里双循环的时间复杂度为O(n²),当数据量大的时候,太消耗性能了,因此需要优化一下,

// 1.拆分后台数据,构造年级回显
      this.options1 = this.echoList.map(item => {
        item.courseList.forEach(val => {
          courseList.push(val)
        })
        return {
          value: item.grade['id'],
          label: item.grade['gradeName']
        }
      })

// 优化代码,拆分双层遍历,降低时间复杂度,O(n)
 this.echoList.map(item => {return item.courseList}).forEach(val =>{
        courseList.push(...val)
    })
    this.options1 =  echoList.map(item =>{
            return {
                    value: item.grade['id'],
                    label: item.grade['gradeName']
                }
    })

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • vue element-ui实现input输入框金额数字添加千分位

    在util.js中定义方法 包含金额添加过滤千分位,验证金额格式等 const MoneyTest = /((^[1-9]\d*)|^0)(\.\d{0,2}){0,1}$/; // 金额添加千分位 const comdify = function (n) { if(!n) return n; let str = n.split('.'); let re = /\d{1,3}(?=(\d{3})+$)/g; let n1 = str[0].replace(re, "$&,");

  • vue Element-ui input 远程搜索与修改建议显示模版的示例代码

    html: <template> <el-autocomplete popper-class="my-autocomplete" custom-item="my-remote" v-model="state" :fetch-suggestions="querySearch" placeholder="默认空" icon="close" :on-icon-click=&q

  • Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

    这篇博客主要介绍树形控件的两个小小的功能: 下拉菜单 输入过滤框 以CSS样式为主,也会涉及到Vue组件和element组件的使用. 对于没有层级的数据,我们可以使用表格或卡片来展示.要展示或建立层级关系,就一定会用到树形组件了. 使用Vue + Element UI,构建出最基本的树如下图所示: 现在我们就要在这个基础上进行改造,使页面更加符合我们的交互场景. 下拉菜单 将下拉菜单嵌到树节点中,使操作更加简便.紧凑. 效果演示 效果如图: 图示1:悬浮在树节点状态 图示2:点击三个点图标状态

  • vue使用element-ui的el-input监听不了回车事件的解决方法

    原因 今天在使用element-ui时,el-input组件监听不了回车事件,如下代码没有想要的效果: <el-input class="search-input" placeholder="请输入内容" v-model="searchText" @keyup.enter="search()"></el-input> 原因应该是element-ui自身封装了一层input标签之后影响了事件的监听,在el

  • vue2.0结合Element实现select动态控制input禁用实例

    今天有一个盆友问小颖,怎么实现用select动态控制input禁用,也就是说,input默认是可编辑的,但是每当我选一次select,input就会变成禁用,虽然小颖不知道她为什么这样做,因为小颖觉得为什么不直接把input设置成禁用的而要用动态的,选一次select禁用一次input,也就是说,input只有在select是没有点击过的时候是可编辑的,但凡我改变一次select的值,input就要被设置成禁用,其实没有必要,因为第一次设置成禁用后面已经不能再改变input的值了,不过当时小颖也

  • vue element table中自定义一些input的验证操作

    官网原话 Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可. 表单 el-form表单必备以下三个属性: :model="ruleForm" 绑定的数据内容 :rules="rules" 动态绑定的rules,表单验证规则 ref="ruleForm" 绑定的对象 template模块 其实问题关键就在于如何给el-form-item动态绑定p

  • Vue+Element一步步实现动态添加Input_输入框案例

    目录 输入式动态添加 单选式动态添加 组合式动态添加 组合式动态添加(回传名称) 单选.多选组合式 数据回显 完整示例 总结 单选切换多选(补充) 下拉框渲染卡顿问题(补充) 双循环遍历优化 输入式动态添加 输入式:即input的值由用户输入:例如:通过自定义用户标签,给用户动态添加多个标签. <template> <div class="app"> <div v-for="item in table" :key="item.

  • vue+element table表格实现动态列筛选的示例代码

    需求:在用列表展示数据时,出现了很多项信息需要展示导致表格横向特别长,展示就不够明晰,用户使用起来可能会觉得抓不住自己的重点. 设想实现:用户手动选择表格的列隐藏还是展示,并且记录用户选择的状态,在下次进入该时仍保留选择的状态. 效果图如下: 原: 不需要的关掉默认的勾选: 实现代码: HTML部分就是用一个多选框组件展示列选项 用v-if="colData[i].istrue"控制显示隐藏,把列选项传到checkbox里再绑定勾选事件. <el-popover placemen

  • 关于vue中根据用户权限动态添加路由的问题

    根据用户的权限,展示不同的菜单页. 知识点 路由守卫(使用了前置守卫):根据用户角色判断要添加的路由 vuex:保存动态添加的路由 难点 每次路由发生变化时都需要调用一次路由守卫,并且store中的数据会在每次刷新的时候清空,因此需要判断store中是否有添加的动态路由. (若没有判断 则会一直添加 导致内存溢出) 根据角色判断路由 过滤动态路由 判断每条路由角色是否与登录传入的角色一致 <template> <div> <el-menu :default-active=&q

  • Vue Element Sortablejs实现表格列的拖拽案例详解

    1. css:    dragTable.css @charset "UTF-8"; .w-table{ height: 100%; width: 100%; float: left; } /* 拖动过程中,鼠标显示样式 */ .w-table_moving .el-table th .thead-cell{ cursor: move !important; } .w-table_moving .el-table__fixed{ cursor: not-allowed; } .w-ta

  • vue 使用async写数字动态加载效果案例

    父组件 <interval-number :number-content="blockHeight" v-if="blockHeight>0"></interval-number> import IntervalNumber from './IntervalNumber.vue' components:{ IntervalNumber, } 子组件 <template> <span class="Interv

  • vue+ElementUI实现订单页动态添加产品数据效果实例代码

    这两天学习了ElementUI基于vue2.0开发学习,这个知识点挺多的,而且很重要,所以,今天添加一点小笔记. 使用vue2.0(ElementUI基于vue2.0)+ElementUI(饿了么出品)实现的在订单页面动态添加产品的效果,并自动计算总价.代码直接保存为html文档,使用浏览器打开即可查看效果. 效果图: <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-U

  • Vue form表单动态添加组件实战案例

    今天我们来给大家介绍下在Vue开发中我们经常会碰到的一种需求场景,就是在form中我们需要动态的增加组件模块,效果如下: 这种效果实现其实就是对 v-for 指令的一种使用,组件不是必须的,只是为了将这部门的代码我们单独的拎出来,便于查看,好了,话不多说,我们来看下具体怎么来实现. 案例效果的实现 1.创建组件 首先我们创建一个单独的组件,同时在 template 中定义我们的表单元素,此处使用的是 element UI 来实现效果. 2.import组件 我们需要在父组件中引入创建的组件,并通

  • vue element 中的table动态渲染实现(动态表头)

    通过在vue中使用element的table表格,实现数据动态渲染,并且动态渲染表头.通过在父组件中引入子组件表格,然后向子组件传递表格数据和表头数据. 子组件table中template模板 <el-table :data="this.tableData" height="400px" max-height="400px" size="small" row-class-name="row" cell

  • Vue+Element实现动态生成新表单并添加验证功能

    首先有一个这样的需求,表单中默认有一个联系人信息,用户可以再添加新的联系人信息 点击添加更多联系人之后 官方文档中有写用v-for来实现新增表单,但是那是单表单的新增,现在多表单的新增,可以考虑的实现方法是先写死一个必须的表单,需要新增的两个表单放在一个div里,在div中使用v-for生成,达到同时新增的效果 代码如下 //必填一个联系人的表单 <el-form-item class="rules" label="通知对象:" prop="noti

  • vue element动态渲染、移除表单并添加验证的实现

    又接到新需求了吧~~ 背景 在一个大表单里,有可能会出现这种需求,用户可以自己操作动态添加.移除表单,更加个性化的效果. 常见于填写个人信息.附加内容的表单 例如: "工作经历"可以用户自己点击继续添加按钮,在原有的表单后面 append 多一个表单,不需要就点击右上方 X 按钮移除 问题 在实现之前,提出几个问题 vue 怎么动态渲染或移除表单上去 v-model 怎么绑定动态添加表单的 value 值 动态新增的表单如何验证 动态表单怎么填写对应的 prop ... 好吧,我当时也

随机推荐