- 安装 element-ui 依赖,按需依赖,性能更优
npm i element-ui -S
-
main.js
引入依赖,加入如下代码:
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
- 注册局部组件
SelectTree.vue
,代码如下:
<template>
<el-select :value="valueTitle" :clearable="clearable" @clear="clearHandle">
<el-option :value="valueTitle" :label="valueTitle" class="options">
<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: {
value:'id', // ID字段名
label: 'title', // 显示名称
children: 'children' // 子级字段名
}
},
// 选项列表数据(树形结构的对象数组)
options:{ type: Array, default: [] },
// 初始值
value:{ type: Number, default: null },
// 可清空选项
clearable:{ type:Boolean, default: true },
// 自动收起
accordion:{ type:Boolean, default: false }
},
data() {
return {
valueId: null,
valueTitle:'',
defaultExpandedKey:[]
}
},
mounted(){
this.valueId = this.value, // 初始值
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.initScroll()
},
// 初始化滚动条
initScroll(){
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>
<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>
- 使用到的地方,代码如下:
<template>
<div>
<h1>{{`基于Element-UI组件改造的树形选择器`}}</h1>
<!-- 调用树形下拉框组件 -->
<SelectTree
:props="props"
:options="optionData"
:value="valueId"
:clearable="isClearable"
:accordion="isAccordion"
@getValue="getValue($event)"/>
</div>
</template>
<script>
import SelectTree from "@/components/SelectTree.vue";
export default {
components: {
SelectTree
},
data() {
return {
isClearable:true, // 可清空(可选)
isAccordion:true, // 可收起(可选)
valueId:20, // 初始ID(可选)
props:{ // 配置项(必选)
value: 'id',
label: 'name',
children: 'children',
// disabled:true
},
// 选项列表(必选)
list:[
{id:1,parentId:0,name:"一级菜单A",rank:1},
{id:2,parentId:0,name:"一级菜单B",rank:1},
{id:3,parentId:0,name:"一级菜单C",rank:1},
{id:4,parentId:1,name:"二级菜单A-A",rank:2},
{id:5,parentId:1,name:"二级菜单A-B",rank:2},
{id:6,parentId:2,name:"二级菜单B-A",rank:2},
{id:7,parentId:4,name:"三级菜单A-A-A",rank:3},
{id:8,parentId:7,name:"四级菜单A-A-A-A",rank:4},
{id:9,parentId:8,name:"五级菜单A-A-A-A-A",rank:5},
{id:10,parentId:9,name:"六级菜单A-A-A-A-A-A",rank:6},
{id:11,parentId:10,name:"七级菜单A-A-A-A-A-A-A",rank:7},
{id:12,parentId:11,name:"八级菜单A-A-A-A-A-A-A-A",rank:8},
{id:13,parentId:12,name:"九级菜单A-A-A-A-A-A-A-A-A",rank:9},
{id:14,parentId:13,name:"十级菜单A-A-A-A-A-A-A-A-A-A",rank:10},
{id:15,parentId:0,name:"一级菜单C",rank:1},
{id:16,parentId:0,name:"一级菜单C",rank:1},
{id:17,parentId:0,name:"一级菜单C",rank:1},
{id:18,parentId:0,name:"一级菜单C",rank:1},
{id:19,parentId:0,name:"一级菜单C",rank:1},
{id:20,parentId:0,name:"一级菜单C",rank:1},
{id:21,parentId:0,name:"一级菜单C",rank:1},
{id:22,parentId:0,name:"一级菜单C",rank:1},
{id:23,parentId:0,name:"一级菜单C",rank:1},
{id:24,parentId:0,name:"一级菜单C",rank:1},
{id:25,parentId:0,name:"一级菜单C",rank:1},
{id:26,parentId:0,name:"一级菜单C",rank:1},
{id:27,parentId:0,name:"一级菜单C",rank:1},
{id:28,parentId:0,name:"一级菜单C",rank:1},
{id:29,parentId:0,name:"一级菜单C",rank:1},
{id:30,parentId:0,name:"一级菜单C",rank:1},
{id:31,parentId:0,name:"一级菜单C",rank:1},
{id:32,parentId:0,name:"一级菜单C",rank:1},
{id:33,parentId:0,name:"一级菜单C",rank:1},
{id:34,parentId:0,name:"一级菜单C",rank:1},
{id:35,parentId:0,name:"一级菜单C",rank:1},
{id:36,parentId:0,name:"一级菜单C",rank:1},
{id:37,parentId:0,name:"一级菜单C",rank:1},
{id:38,parentId:0,name:"一级菜单C",rank:1},
{id:39,parentId:0,name:"一级菜单C",rank:1},
{id:40,parentId:0,name:"一级菜单end",rank:1}
]
};
},
computed:{
/* 转树形数据 */
optionData(){
let cloneData = JSON.parse(JSON.stringify(this.list)) // 对源数据深度克隆
return cloneData.filter(father=>{ // 循环所有项,并添加children属性
let branchArr = cloneData.filter(child=>father.id == child.parentId); // 返回每一项的子级数组
branchArr.length>0 ? father.children=branchArr : '' //给父级添加一个children属性,并赋值
return father.parentId==0; //返回第一层
});
}
},
methods:{
// 取值
getValue(value){
this.valueId = value
console.log(this.valueId);
}
}
};
</script>
- 效果如下:
树形选择器
网友评论