借鉴了网上前端大佬的实现,加上自己在使用过程中发现的一些BUG,做了一些改进。主要可以支持动态表单的特性及v-model,支持禁用,支持放在表单中使用,下面请看代码。
主要借鉴文章:https://wiill.blog.csdn.net/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>
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
// 这里要延迟执行,否则有BUG
setTimeout(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 = null
this.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.value
this.initHandle()
}
}
}
</script>
<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: {
value: 'key', // ID字段名
label: 'title', // 显示名称
children: 'children' // 子级字段名
}
[
{
"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
}
]