一、先看效果
二、组件具体实现
借鉴了网上前端大佬的实现,加上自己在使用过程中发现的一些BUG,做了一些改进。主要可以支持动态表单的特性及v-model,支持禁用,支持放在表单中使用,下面请看代码。
主要借鉴文章:https://wiill./article/details/88604270
组件模板
<template><el-select :value="valueTitle" :disabled="disabled" :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
<script>export default {name: 'ebs-tree-select',props:{/* 配置项 */props:{type: Object,default:()=>{return {value:'id', // ID字段名label: 'title', // 显示名称children: 'children' // 子级字段名}}},/* 选项列表数据(树形结构的对象数组) */options:{type: Array,default: ()=>{return [] }},/* 初始值 */value:{type: String,default: ()=>{return null }},/* 可清空选项 */clearable:{type:Boolean,default:()=>{return true }},/* 自动收起 */accordion:{type:Boolean,default:()=>{return false }},disabled: {type:Boolean,default:()=>{return false }}},data() {return {valueId:this.value, // 初始值valueTitle:'',defaultExpandedKey:[]}},mounted(){this.initHandle()},methods: {// 初始化值initHandle(){// alert('this.valueId=' + this.valueId)let that = this// 这里要延迟执行,否则有BUGsetTimeout(function() {if(that.valueId){that.valueTitle = that.$refs.selectTree.getNode(that.valueId).data[that.props.label]// 初始化显示that.$refs.selectTree.setCurrentKey(that.valueId) // 设置默认选中that.defaultExpandedKey = [that.valueId]// 设置默认展开} else {that.valueTitle = null // 初始化显示that.$refs.selectTree.setCurrentKey(null) // 设置默认选中}},200)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.$emit('input',this.valueId)this.defaultExpandedKey = []},// 清除选中clearHandle(){this.valueTitle = ''this.valueId = nullthis.defaultExpandedKey = []this.clearSelected()//this.$emit('getValue',null)this.$emit('input',null)},/* 清空选中样式 */clearSelected(){let allNode = document.querySelectorAll('#tree-option .el-tree-node')allNode.forEach((element)=>element.classList.remove('is-current'))}},watch: {value(){this.valueId = this.valuethis.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>
具体使用
<ebs-tree-select v-else-if="field.view=='cat_tree'" :props="treeSelectProps" v-model="form[field.fieldName]":options="catTreeData[field.fieldName]" v-bind:disabled="isView"></ebs-tree-select>
补充说明:
使用 treeSelectProps 解决数据字段名不匹配问题treeSelectProps: {value: 'key', // ID字段名label: 'title', // 显示名称children: 'children' // 子级字段名}
因为我这里是动态表单字段,所以是 form[field.fieldName],你可以直接写form.xxxx因为是动态表单,考虑一个表单有多个选树字段,故这里写catTreeData[field.fieldName],非我这类场景,你可以直接写catTreeData,里面就说数组对象,多层级即可,可参考如下JSON:
[{"key": "1462626865326317569","title": "基础管理","icon": null,"parentId": "1462626811047829505","value": null,"code": "B03A01","children": null,"leaf": true},{"key": "1462626933466980354","title": "在线开发","icon": null,"parentId": "1462626811047829505","value": null,"code": "B03A02","children": [{"key": "1462627031668219905","title": "表单开发","icon": null,"parentId": "1462626933466980354","value": null,"code": "B03A02A01","children": null,"leaf": true},{"key": "1462627069307904002","title": "报表配置","icon": null,"parentId": "1462626933466980354","value": null,"code": "B03A02A02","children": null,"leaf": true}],"leaf": false}]