1.組件調用代碼
<template>
<div id="app"> <h1>{{`基於Element-UI組件改造的樹形選擇器`}}:</h1> <!-- 調用樹形下拉框組件 --> <!-- 下拉樹 --> <selectbutton :props="props" :options="optionData" :value="valueId" :clearable="isClearable" :accordion="isAccordion" @getValue="getValue($event)" height="200" ></selectbutton> ID為:{{valueId}} </div> </template> 復制代碼
調用組件的數據
<script>
import SelectTree from "./components/treeSelect.vue"; export default { name: "app", components: { SelectTree }, data() { return { isClearable: true, // 可清空(可選) isAccordion: true, // 可收起(可選) valueId: 1, // 初始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: 0, name: "一級菜單C", rank: 1 }, { id: 10, 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> 復制代碼
2.組件封裝
<template>
<el-select :value="valueTitle" :clearable="clearable" @clear="clearHandle" ref="treeSelect"> <el-input class="selectInput" :placeholder="placeholder" v-model="filterText"> </el-input> <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" :filter-node-method="filterNode" @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 } }, placeholder:{ type:String, default:()=>{return "檢索關鍵字"} } }, data() { return { filterText: '', 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.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 = [] if(!node.children || !node.children.length) { //補錄選擇完選項彈框不能收起 this.$refs.treeSelect.blur() } }, // 清除選中 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')) }, filterNode(value, data) { if (!value) return true; return data.name.indexOf(value) !== -1; } }, watch: { value(){ this.valueId = this.value this.initHandle() }, filterText(val) { this.$refs.selectTree.filter(val); } }, }; </script> 復制代碼
3.樣式修改
<!-- Add "scoped" attribute to limit CSS to this component only --> <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; } .selectInput{ padding: 0 5px; box-sizing: border-box; } </style>