问题描述:
el-select下拉框要求实现全选功能。具体功能包括:
- 当选择【全选】时,所有选项全部被勾选;
- 当选择【反选】时,已选择选项变为未选择选项,未选项变为已选项
- 当选择【清空】时,所有选项变为未选
如下图:
解决方法:
1、给el-select增加【全选】【清空】【反选】按钮
2、为el-select绑定change事件和remove-tag事件,具体实现全选功能写在事件中
实例代码:
组件:
<el-form-item label="关联设备" v-if="node.nodeId != 11 && node.nodeId != 21 && node.nodeId != 22 "> <el-select style="width: 100% " v-model="node.devices" size="small" multiple collapse-tags filterable placeholder="请选择" :filter-method="dataDevFilter"> <div class="select_up"> <el-button type="text" v-on:click="selectDevAll"> <i class="el-icon-circle-check" /> 全选</el-button> <el-button type="text" v-on:click="removeDevTag"> <i class="el-icon-close" /> 清空</el-button> <el-button type="text" v-on:click="selectDevReverse"> <i class="el-icon-copy-document" /> 反选</el-button> </div> <div class="select_list"> <el-option v-for="item in devOptions" :key="item.deviceCode" :label="item.deviceName" :value="item.deviceCode"> </el-option> </div> </el-select> </el-form-item>
复制
js方法:
//用户列表----start //清空操作 removeTag() { this.node.users = [] }, //全选操作 selectAll(val) { this.options.map(item => { if(!this.node.users.includes(item.userName)){ this.node.users.push(item.userName) } }) console.log(this.node.users) }, //反选操作 selectReverse(val) { val = [] this.options.map(item => { let index = this.node.users.indexOf(item.userName); //判断现有选中数据是否包含如果不包含则进行反选数据 if (index != -1) { } else { val.push(item.userName) } }) this.node.users = val }, dataFilter(query) { // this.value = val //给绑定值赋值 if(query == ''){ //val不存在还原数组 this.options= this.userList }else{ let result = [] //存储符合条件的下拉选项 this.userList.forEach(val=>{ if(val.nickName.indexOf(query)!=-1) result.push(val) }) this.options = result } }, //用户列表----end
复制
css样式:
<style> .el-select-dropdown__list { height: 100%; overflow: hidden; } .select_up { padding: 0 14px; font-size: 14px; position: absolute; z-index: 99999; background-color: white; top: 0px; width: 100%; border-radius: 5px 5px 0 0; ::v-deep .el-button { color: #bcbcbc; font-size: 14px; i { font-size: 14px; } } ::v-deep .el-button:hover { color: #409EFF; } .el-button+.el-button { margin-left: 6px; } } .select_list { margin-top: 25px; } </style>
复制
完整组件
子组件代码如下,请注意代码注释的讲解:
1、props里面需定义value(双向绑定默认的变量,可自定义),父组件通过v-model绑定的fatherValue 会传给子组件props的 value
2、子组件的input框添加@change事件触发sendMsg,sendMsg向父组件传递change事件(双向绑定默认事件,可自定义),同时传递childValue的值
3、添加value的watch监听,当value变化时传递最新值给childValue
<template> <div> <el-select style="width: 100% " v-model="orgData" size="small" multiple collapse-tags filterable placeholder="请选择" :filter-method="dataFilter" @change="sendMsg()" > <div class="select_up"> <el-button type="text" v-on:click="selectAll"> <i class="el-icon-circle-check" /> 全选</el-button> <el-button type="text" v-on:click="removeTag"> <i class="el-icon-close" /> 清空</el-button> <el-button type="text" v-on:click="selectReverse"> <i class="el-icon-copy-document" /> 反选</el-button> </div> <div class="select_list"> <el-option v-for="item in options" :key="item.userName" :label="item.nickName" :value="item.userName"> </el-option> </div> </el-select> </div> </template> <script> export default { props: { value: { type: Array, required: [] }, userList: { type: Array, required: [] }, options: { type: Array, required: [] }, }, watch: { //监听value变化(slect控件不是必要,暂时不明) value(newValue, oldValue) { this.orgData = newValue; } }, data() { return { orgData: [],//选中数据 } }, methods: { //用户列表----start //清空操作 removeTag() { this.orgData = [] }, //全选操作 selectAll(val) { this.options.map(item => { if(!this.orgData.includes(item.userName)){ this.orgData.push(item.userName) } }) console.log(this.orgData) }, //反选操作 selectReverse(val) { val = [] this.options.map(item => { let index = this.orgData.indexOf(item.userName); //判断现有选中数据是否包含如果不包含则进行反选数据 if (index != -1) { } else { val.push(item.userName) } }) this.orgData = val }, dataFilter(query) { // this.value = val //给绑定值赋值 if(query == ''){ //val不存在还原数组 this.options= this.userList }else{ let result = [] //存储符合条件的下拉选项 this.userList.forEach(val=>{ if(val.nickName.indexOf(query)!=-1) result.push(val) }) this.options = result } }, //用户列表----end sendMsg(){ //input是默认双向绑定事件,select控件也可以用input给父组件传递数据 this.$emit('input',this.orgData) } } } </script> <style scoped lang="scss"> .el-select-dropdown__list { height: 100%; overflow: hidden; } .select_up { padding: 0 14px; font-size: 14px; position: absolute; z-index: 99999; background-color: white; top: 0px; width: 100%; border-radius: 5px 5px 0 0; ::v-deep .el-button { color: #bcbcbc; font-size: 14px; i { font-size: 14px; } } ::v-deep .el-button:hover { color: #409EFF; } .el-button+.el-button { margin-left: 6px; } } .select_list { margin-top: 25px; } </style>
复制
父组件引用
<script> import userSelect from '@/views/processEngine/unit/userSelect' export default { components: { userSelect,deviceSelect }, </script>
复制
<el-form-item label="关联人员"> <userSelect v-model="node.users" :userList="userList" :options="userList" ></userSelect> </el-form-item>
复制
注意:
当传值的时候,v-model触发了input事件, 而组件中的props属性默认就使用传入的value值, 但是回传的时候 是通过emit触发的input事件。 如果没有emit, 那么就不会触发input 也就不会反向传值