前言:由于做项目需要一个树形选择器,项目用的也是element-ui框架,然而它自带的选择器组件没有树形选项,又不想引入其他的框架组件,于是自己利用el-select和el-tree改造了一个,感觉还挺好用的,就封装成了一个组件,如下图:
element-ui的el-select组件的选项只能是列表形式:
改造后的树形选择器:
简介:此树形选择器组件是基于elment-ui框架的el-select和el-tree组件的基础上改造的,其解决了原el-select组件的选项列表不能是树形的问题,集合了前两个组件的属性和方法封装成了一个组件,引入即可使用。其实现了树形列表、默认展开、默认选中、清空选值等功能,基本上可以满足大部分选择器的使用需求。
主要代码
组合el-select和el-tree组件:
<template> <el-select :value="valueTitle" :clearable="clearable" @clear="clearHandle"> <el-option :value="valueTitle" :label="valueTitle"> <el-tree id="tree-option" ref="selectTree" :accordion="accordion" :data="options" :props="props" :node-key="props.value" :default-expanded-keys="defaultExpandedKey" @node-click="handleNodeClick"> </el-tree> </el-option> </el-select> </template>
封装组件:
<script> export default { name: "el-tree-select", props:{ /* 配置项 */ props:{ type: Object, default:()=>{ return { value:'id', // ID字段名 label: 'title', // 显示名称 children: 'children' // 子级字段名 } } }, /* 选项列表数据(树形结构的对象数组) */ options:{ type: Array, default: ()=>{ return [] } }, /* 初始值 */ value:{ type: Number, default: ()=>{ return null } }, /* 可清空选项 */ clearable:{ type:Boolean, default:()=>{ return true } }, /* 自动收起 */ accordion:{ type:Boolean, default:()=>{ return false } }, }, data() { return { valueId:this.value, // 初始值 valueTitle:'', defaultExpandedKey:[] } }, mounted(){ this.initHandle() }, methods: { // 初始化值 initHandle(){ if(this.valueId){ this.valueTitle = this.$refs.selectTree.getNode(this.valueId).data[this.props.label] // 初始化显示 this.$refs.selectTree.setCurrentKey(this.valueId) // 设置默认选中 this.defaultExpandedKey = [this.valueId] // 设置默认展开 } this.$nextTick(()=>{ let scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0] let scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar') scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;' scrollBar.forEach(ele => ele.style.width = 0) }) }, // 切换选项 handleNodeClick(node){ this.valueTitle = node[this.props.label] this.valueId = node[this.props.value] this.$emit('getValue',this.valueId) this.defaultExpandedKey = [] }, // 清除选中 clearHandle(){ this.valueTitle = '' this.valueId = null this.defaultExpandedKey = [] this.clearSelected() this.$emit('getValue',null) }, /* 清空选中样式 */ clearSelected(){ let allNode = document.querySelectorAll('#tree-option .el-tree-node') allNode.forEach((element)=>element.classList.remove('is-current')) } }, watch: { value(){ this.valueId = this.value this.initHandle() } }, }; </script>
css样式:
<style scoped> .el-scrollbar .el-scrollbar__view .el-select-dropdown__item{ height: auto; max-height: 274px; padding: 0; overflow: hidden; overflow-y: auto; } .el-select-dropdown__item.selected{ font-weight: normal; } ul li >.el-tree .el-tree-node__content{ height:auto; padding: 0 20px; } .el-tree-node__label{ font-weight: normal; } .el-tree >.is-current .el-tree-node__label{ color: #409EFF; font-weight: 700; } .el-tree >.is-current .el-tree-node__children .el-tree-node__label{ color:#606266; font-weight: normal; } </style>
查看demo
注意:此树形选择器要求的值(options)必须是树形对象数组,如你的值是扁平数据,需转换成树形数据。可参考js实现无限层级树形数据结构(创新算法)