实现思路:给el-tree-node__children添加伪类画竖线,给el-tree-node__content添加伪类画横线,通过位置调整让竖线和直线正好连在一起。图标通过icon-class先去除原先图标后根据之前图标的类名重添加置背景图。这样还可以保留之前图标的点击旋转
<!--
* @fileName: GroupChatTree.vue.vue
!-->
<template>
<div :class="ns.b()">
<el-scrollbar style="height: 100%">
<el-tree
class="treeCont"
:indent="0"
:data="treeData"
:props="defaultProps"
highlight-current
check-strictly
current-node-key="id"
node-key="id"
default-expand-all
@node-click="handleNodeClick"
icon-class="empty-icon"
>
<template #default="{ node, data }">
<div :class="[ns.b('label'), ns.is('leftLable', node?.isLeaf), ns.is('active', node?.isLeaf && data?.id === treeValue)]" :title="data?.label">
<img :src="$utils.format.getIconByAppType(data.appType, data.type)" width="18px" height="18px" class="mr6" />
<div :class="ns.e('label')">{{ data?.label || '' }}</div>
</div>
</template>
</el-tree>
</el-scrollbar>
</div>
</template>
<script>
import { NameSpace } from '@/common/utils/nameSpace'
import { getBelongAccountAndGroup } from '@/common/api/analysisModuleApi'
export default {
components: {},
model: {
prop: 'value',
event: 'changeEvent'
},
props: {
value: {
type: String,
default: ''
},
api: {
type: Function,
required: false
},
params: {
type: Object,
default: () => {}
}
},
data() {
return {
ns: new NameSpace('GroupChatTree'),
defaultProps: {
children: 'children',
label: 'label'
},
// interface ITreeData {
// id: string | number
// accountId: String, // 账户id(可能重复)
// label:String
// appType:String
// type:String
// children:ITreeData[]
// }
treeData: []
}
},
computed: {
// 树的value
treeValue: {
get() {
return this.value
},
set(val) {
this.$emit('changeEvent', val)
// //递归树通过id找到对应节点并返回
const item = this.findItemById({ children: this.treeData }, val)
// console.log('00000item', item)
this.$emit('change', { val, item, treeData: this.treeData })
}
}
},
watch: {
params: {
handler() {
this.init()
},
deep: true
}
},
created() {
this.init()
},
mounted() {},
methods: {
async init() {
let res = {}
if (this.api) {
res = await this.api(this.params)
} else {
res = await getBelongAccountAndGroup({
suspectId: this.$cookies.get('suspectId') || this.$store.state?.project.curSuspectId
})
}
if (!res?.data || !Array.isArray(res?.data)) return
this.treeData = res?.data || []
const { id } = this.getFirstLeafNode(res.data[0])
//默认选中第一个节点的第一个叶子节点
this.treeValue = id
},
handleNodeClick(data, node) {
if (!node.isLeaf) return
this.treeValue = data?.id || ''
// this.$emit('changeEvent', (this.treeValue = data?.id || ''))
},
//递归获取第一个节点的第一个叶子节点
getFirstLeafNode(item) {
if (item.children && Array.isArray(item.children) && item.children.length) {
return this.getFirstLeafNode(item.children[0])
} else {
return item
}
},
// 通过id查找节点
findItemById(tree, id) {
// 检查当前节点是否匹配
if (tree.id === id) {
return tree
}
// 如果当前节点有子节点,递归查找
if (tree.children && tree.children.length > 0) {
for (let i = 0; i < tree.children.length; i++) {
const result = this.findItemById(tree.children[i], id)
if (result) {
return result
}
}
}
// 如果没有找到匹配的节点,返回 null
return null
}
}
}
</script>
<style lang="scss" scoped>
.dyt-GroupChatTree {
height: 100%;
.dyt-GroupChatTree-label {
width: calc(100% - 28px);
height: 100%;
display: flex;
align-items: center;
.dyt-GroupChatTree__label {
white-space: nowrap; /* 不换行 */
overflow: hidden; /* 溢出隐藏 */
text-overflow: ellipsis; /* 溢出显示省略号 */
}
}
.is-leftLable {
width: 100% !important;
padding-left: 5px;
box-sizing: border-box;
}
}
.is-active {
color: #4b8dff;
}
/deep/ .custom-scrollbar .el-scrollbar__bar {
right: 20px; /* 向右移动 20px */
}
/deep/ .el-scrollbar__wrap {
padding-right: 12px;
}
/deep/ .el-tree-node {
//margin-bottom: 6px;
padding: 3px 0;
}
::v-deep .treeCont {
.el-tree-node__children {
position: relative;
padding-left: 24px;
.el-tree-node__content {
position: relative;
}
.el-tree-node__content:before {
content: '';
width: 12px;
height: 1px;
background-color: #ccc;
position: absolute;
left: -16px;
top: 50%;
}
}
.el-tree-node__children:before {
content: '';
width: 24px;
height: 100%;
border-left: 1px solid #ccc;
position: absolute;
left: 8px;
top: -16px;
}
}
//菜单自定义按钮
/deep/ .el-tree-node__expand-icon {
background-image: url('../../../assets/images/analysisModule/tree-open.png');
background-size: cover; /* 或者你可以根据需要调整大小 */
width: 16px !important; /* 根据图片大小调整 */
height: 16px !important; /* 根据图片大小调整 */
margin-right: 5px !important;
margin-bottom: 0 !important;
}
/deep/ .expanded {
background-image: url('../../../assets/images/analysisModule/tree-close.png') !important;
width: 14px !important; /* 根据图片大小调整 */
height: 14px !important; /* 根据图片大小调整 */
margin-right: 6px !important;
margin-left: 1px !important;
}
//叶子节点的icon不显示
/deep/ .is-leaf {
display: none !important;
}
</style>