首页 前端知识 Element——el-select多选器

Element——el-select多选器

2024-02-14 09:02:31 前端知识 前端哥 992 59 我要收藏

本文章默认全程使用Vue2和Element,如果有使用Vue3或者Element Plus的地方会有提示!

基本使用

使用multiple 属性开启选择框的多选功能,此时v-model的值为当前选中值(:value绑定的值)所组成的数组(可以仍然将其设置为字符串,但当后续获取其中的值时会自动转换成数组)。

<template>
  <el-select v-model="value" multiple placeholder="请选择"> <!-- value是双向绑定的值 -->
    <el-option
      v-for="item in options"  
      :key="item.value" 
      :label="item.label"
      :value="item.value"><!-- options是下拉列表选项;label为下拉列表在页面上显示的内容;value为页面显示标签实际上对应的值; -->
    </el-option>
  </el-select>
</template>

<script>
  export default {
    data() {
      return {
        options: [ // 下拉列表
            { 
              value: '选项1',
              label: '黄金糕'
            }, 
            {
              value: '选项2',
              label: '双皮奶'
            }
        ],
        value: [] // value值可以为字符串(""),但是绑定值改变后获取的仍然是数组 
      }
    }
  }
</script>

数据回显

场景使用多选的选择器,获取到默认的数据后,让多个回显标签显示在多选的选择器中。

思路:其实这个不难,只要把数据赋值给v-model绑定的值就可以了,但是一定要注意其中el-optionvalue的对应,要想获取到value后直接回显示对应的label,就必须与对应value的值完全相等(注意是完全相等,相同数字的字符串和数字类型都不行,必须是同一类型)!!!

对于多个数据来说(给el-select开启multiple),返回的是这个value数组,所以对于回显需要回填的数据也是这个value值的数组。

<template>
  <el-select v-model="value" multiple placeholder="请选择">
    <el-option
      v-for="item in options"  
      :key="item.value" 
      :label="item.label"
      :value="item.value">
    </el-option>
  </el-select>
</template>

<script>
  export default {
    data() {
      return {
        options: [
            { 
              value: '选项1',
              label: '黄金糕'
            }, 
            {
              value: '选项2',
              label: '双皮奶'
            }
        ],
        value: ['选项1', '选项2'] // 根据其中的value值进行回显,回显的数据为对应value值对象的label值
      }
    }
  }
</script>

回显修改

场景正常的回显数组是以value组成的字符串数组,我们可以通过这个字符串value值来找到 options 下对应的对象,但是我们需要手动筛选一遍,过于麻烦。

思路:既然回显的数组是根据el-option下绑定的value值来确定的,那么在设置value值时直接设置整个对象,这样在回显时可以采用对象数组的形式,更方便我们做一些其他的操作。

<template>
  <el-select v-model="value" multiple placeholder="请选择">
    <el-option
      v-for="item in options"  
      :key="item.value" 
      :label="item.label"
      :value="item"> <!-- 直接将value的值设置为options中的每个对象 -->
    </el-option>
  </el-select>
</template>

<script>
  export default {
    data() {
      return {
        options: [
            { 
              value: '选项1',
              label: '黄金糕'
            }, 
            {
              value: '选项2',
              label: '双皮奶'
            }, 
            {
              value: '选项3',
              label: '虾饺'
            }
        ],
        value: [
            {
              value: '选项2',
              label: '双皮奶'
            }, 
            {
              value: '选项3',
              label: '虾饺'
            }
        ] // 回显的value数组也必须是跟options中的每个对象相对应
      }
    }
  }
</script>

数据显示问题

场景回显的数据是异步从别的地方加载过来的,可以得知代码已经获取到了数据(例如在获取数据之后打印确实有数据的值),但是在页面上并没有正确的渲染出来;或者选择了下拉框里某个值,并没有在页面中正确渲染出已选择的这个值,但是在实际发送的表单项里又有这个值

分析:可能是因为数据层次结构太多,render函数没有自动更新(Vue不能检测到对象属性的添加或删除)。

解决:手动触发更新。

<el-select v-model="value" placeholder="请选择" @change="change()">
      <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
change() {
    this.$forceUpdate();
}

注意:使用这个可能会触发表单校验问题,就是表单项里有值但是表单校验仍然说该值为空。(详细见el-form一章)。

回显数据限制——禁止删除并禁止选择

注意:阅读这章前建议先阅读回显修改一章。

场景点击表格项的编辑按钮出现弹窗或抽屉,其中有该项的具体信息包括需要回显的多选器,回显的数据由于权限的原因需要进行限制,如果该用户没有操作该数据的权限,则对于该用户来说回显数据上的删除按钮不会出现(不能删除该数据),下拉能显示该数据但是无法对其进行点选(禁用状态)。

注:该场景下我们已经得到了该用户没有权限的数据值的列表。

思路:由于el-select的多选回显数据后默认的回显tag上会有一个删除的小叉来提供删除功能,在这里我选择把这个小叉通过css干掉来禁止删除(需要直接操作dom);而禁止下拉选择则是可以直接通过disabled属性过滤掉。

注意:禁用删除功能还可以通过官方remove-tag事件进行处理,该事件多选模式下移除tag时触发,接收一个移除的tag值的回调,我们可以在移除这个tag(数据)时再将数据填回去从而达到没有删除的效果,但是这样删除的小叉还会存在,容易对用户引起误会,所以我才用了直接干掉它的做法。

<template>
  <el-select v-model="value" multiple ref="selectRef" placeholder="请选择">
    <el-option
      v-for="item in rolesList"  
      :key="item.value" 
      :label="item.label"
      :value="item"
      :disabled="!item.isAuth" 
    > <!-- 通过每项对象里是否有isAuth来判断该选项是否禁用 -->
    </el-option>
  </el-select>
</template>

<script>
  export default {
    data() {
      return {
        // this.value(回显的数据)和rolesList(下拉菜单需要显示的数据)都已经通过axios或其他方法请求后端接口拿取到了数据,此处不再详细描述来源,获取的数据的数据结构如下,为了方便操作,两个数据结构大致相同
        rolesList: [
            // {
              // value: '选项2',
              // label: '双皮奶',
              // isAuth: false
            // }
        ],
        value: [
            // {
              // value: '选项2',
              // label: '双皮奶',
              // isAuth: false
            // }
        ]
      }
    },
    methods: {
        getRolesList() {
            let noRoleList = [...]; // 内为没有权限的数据列表(可以是数组对象,也可以是数组字符串等,根据自己的具体需求进行修改;此处为数组对象) @1
            // 抓取小叉的dom元素(span里包裹的i)
            const childrenSpanList = this.$refs.selectRef.$children[0];
            let spanList = childrenSpanList.$el.children;
            
            setTimeout(() => { // @2
                for(let iconEl of spanList) { // 遍历所有的span @3
                    noRoleList.forEach(item => {
                        if (item.name == iconEl.firstElementChild.innerHTML) { // 当前的标签里的名字在无权限的数据列表里
                           iconEl.lastElementChild.style.display = 'none'; // 将删除按钮干掉
                        }
                    })
                }
            })
        }
    },
  }
</script>

@1:此处也可以不需要额外的没有权限的数据列表,可以直接通过回显数据里的isAuth字段来判断是否有权限,然后取出其中的 label 再进行后续操作;万变不离其宗,最终都是为了找出没有权限的数据项然后通过dom操作移除删除图标。

@2:此处的setTimeout()是为了能让 spanList 真正被获取到并对其进行操作(由于Vue的渲染顺序,即使能够打印出 spanList 的数据,在进行循环时也可能为空);Vue 中也有$nextTick()可以用来更新数据,但是这个对于初始打开时的回显并没有效果,故采用了setTimeout()

@3:在el-select的多选器框的dom结构里,每一个多选的 tag 都是包裹在一个 span 标签里,这个 span 标签里有两个元素,一个是用于显示 label( span 标签),一个是用于显示删除小叉的图标( i 标签);所以可以采用firstElementChildlastElementChild来操作对应的dom元素。(详情dom情况自行查看)

转载请注明出处或者链接地址:https://www.qianduange.cn//article/2014.html
标签
elementui
评论
会员中心 联系我 留言建议 回顶部
复制成功!