vue实现下拉多选、可搜索、全选功能
最后的效果就是树形的下拉多选,可选择任意一级选项,下拉框中有一个按钮可以实现全选,也支持搜索功能。
在mounted生命周期里面获取全部部门的数据,handleTree是讲接口返回的数据整理成树形结构,可以自行解决
<div class="LeftText"><span style="color: red; margin-right: 4px">*</span>部门:</div><el-selectv-model="executiveDepartName"filterable:filter-method="selectChange"multiple@visible-change="visibleChange"@remove-tag="seleRemoveTag"style="width: 80%"><el-option style="display: none" value=""></el-option><el-checkboxstyle="width: 100%;height: 40px;line-height: 40px;padding-left: 20px;border-bottom: 1px solid #dcdfe6;"class="allselect":indeterminate="isIndeterminate"v-model="allSelectModule"@change="allselect">全选</el-checkbox><el-cascader-panelref="cascaderModule":key="deptList.length":options="deptList"@change="cascaderChange"style="width: 80%":props="props"filterable:border="false":show-all-levels="false"v-model="executiveDepartment"></el-cascader-panel></el-select></div>
props: {multiple: true,value: "deptId",label: "deptName",checkStrictly: true,emitPath: false,}, allDeptList:[];//所有的部门信息,内部结构为:{deptId:1,deptName:"一级部门"}isSeach:false;//是否搜索状态tempExecutive:[];// 搜索前已选中的数据//搜索查询事件--是因为在cascaderChange事件中,对v-model的值重新赋值,导致下拉选时,会触发el-select的搜索事件,所以加了一个isFilter判断selectChange(val) {if (val !== "") {this.deptList = [];this.deptList = this.allDeptList.filter((item) => {return item.deptName.toLowerCase().indexOf(val.toLowerCase()) > -1;});this.isSeach = true;this.tempExecutive = this.executiveDepartment;} else {if (!this.isFilter) {this.deptList = this.handleTree(this.allDeptList, "deptId");this.isFilter = !this.isFilter;}}},visibleChange(e) {if (e) {this.isSeach = false;this.isFilter = false;this.deptList = this.handleTree(this.allDeptList, "deptId");this.initStatus();}},对全选状态进行重新赋值initStatus() {if (this.executiveDepartment.length == this.allDeptList.length) {this.allSelectModule = true;this.isIndeterminate = false;} else if (this.executiveDepartment.length == 0) {this.allSelectModule = false;this.isIndeterminate = false;} else {this.allSelectModule = false;this.isIndeterminate = true;}},//select框里回显的是选中部门的名称getDeptName() {const result = [];this.executiveDepartment.filter((item) => {this.allDeptList.map((i) => {if (item == i.deptId) {result.push(i.deptName);}});});return result;},seleRemoveTag(val) {if (val) {const result = this.allDeptList.find((item) => {if (item.deptName == val) {return item;}});this.executiveDepartment = this.executiveDepartment.filter((item) => item !== result.deptId);}},// 下拉多选选中时触发的事件cascaderChange() {this.isFilter = true;//如果是搜索状态,讲之前选中的值和搜素状态下的值进行合并和去重,否则,之前选中的值会被清空if (this.isSeach) {this.executiveDepartment = [...new Set([...this.tempExecutive, ...this.executiveDepartment]),];}this.executiveDepartName = this.getDeptName();this.initStatus();},//全选事件allselect() {if (this.allSelectModule) {this.isIndeterminate = false;if (this.isSeach) {this.executiveDepartment = this.deptList.map((item) => item.deptId);this.executiveDepartName = this.getDeptName();} else {this.executiveDepartment = this.getAllIds(this.deptList);this.executiveDepartName = this.getDeptName();}} else {this.executiveDepartment = [];this.executiveDepartName = [];}},getAllIds(nodes) {let ids = [];(function getIds(nodes) {nodes.forEach((node) => {ids.push(node.deptId);if (node.children && node.children.length) {getIds(node.children);}});})(nodes);return ids;},