需求:el-tree只能选中最后一层级的子节点,并且切换树内容时查找树的第一个无子节点的叶节点设置为选中状态
实现效果:
这里选中状态是蓝色高亮,灰色是hover效果
核心思想为el-tree通过 :current-node-key绑定一个选中值,然后通过el-tree的.setCurrentKey方法设置当前选中的值,不能够直接修改:current-node-key绑定的值,不然没效果。
代码:
<template> <div class="datamanage"> <el-card class="left"> <el-row> <p>资料分类形式</p> </el-row> <div class="sortform"> <div class="item" style="margin-right: 7px" @click="changesortform('ywjk')" :class="sortform === 'ywjk' ? 'active1' : ''" > <img :src="require('@/assets/datamanage/源文件库.png')" alt="" /> <span>源文件库</span> </div> <div class="item" style="margin-left: 7px" @click="changesortform('tjk')" :class="sortform === 'tjk' ? 'active2' : ''" > <img :src="require('@/assets/datamanage/统计库.png')" alt="" /> <span>统计库</span> </div> </div> <el-divider></el-divider> <el-tree class="tree_container" :data="treedata" default-expand-all node-key="id" ref="tree" :current-node-key="currennode.id" highlight-current check-strictly :props="defaultProps" :check-on-click-node="false" @node-click="nodeClick" > <span class="custom-tree-node" slot-scope="{ data }"> <span style=" color: #555f6f; font-size: 14px; font-family: MicrosoftYaHei; font-weight: 500; display: flex; align-items: center; " > <i v-if="data.icon" :class="data.icon" class="iconfont" style="font-size: 16px; color: #86909c; margin-right: 10px" ></i> <span v-else style=" display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: #e5e6eb; margin-right: 10px; " ></span >{{ data.label }} </span> </span> </el-tree> </el-card> <el-card class="right"> {{ currennode.label }} </el-card> </div> </template> <script> import { datamanage } from "@/config/datamanage"; export default { components: {}, data() { return { sortform: "ywjk", //资料分类形式 currennode: { id: 7, }, defaultProps: { children: "children", label: "label", }, }; }, created() {}, mounted() {}, computed: { treedata() { return datamanage[this.sortform]; }, }, watch: { treedata: { deep: true, immediate: true, handler(val) { this.$nextTick(() => { this.currennode = this.findNode(this.treedata, (node) => { return !node.children; }); this.$refs.tree.setCurrentKey(this.currennode.id); }); }, }, }, methods: { //改变资料分类形式 changesortform(val) { this.sortform = val; }, //点击节点时间 nodeClick(e, node) { this.$nextTick(() => { if (!e.children) { this.currennode = e; } this.$refs.tree.setCurrentKey(this.currennode.id); console.log(this.currennode); }); }, //查找树节点无子节点的叶节点 findNode(tree, func) { for (const node of tree) { if (func(node)) return node; if (node.children) { const res = this.findNode(node.children, func); if (res) return res; } } return null; }, }, }; </script>
er-tree的层级线样式如下:
.tree_container { ::v-deep.el-tree > .el-tree-node:after { border-top: none; } ::v-deep .el-tree-node { position: relative; padding-left: 16px; } //节点有间隙,隐藏掉展开按钮就好了,如果觉得空隙没事可以删掉 ::v-deep .el-tree-node__expand-icon.is-leaf { display: none; } ::v-deep .el-tree-node__children { padding-left: 16px; } ::v-deep .el-tree-node :last-child:before { height: 38px; } ::v-deep .el-tree > .el-tree-node:before { border-left: none; } ::v-deep .el-tree > .el-tree-node:after { border-top: none; } ::v-deep .el-tree-node:before { content: ""; left: -4px; position: absolute; right: auto; border-width: 1px; } ::v-deep .el-tree-node:after { content: ""; left: -4px; position: absolute; right: auto; border-width: 1px; } ::v-deep .el-tree-node:before { border-left: 1px solid #e5e6eb; bottom: 0px; height: 100%; top: -22px; width: 1px; } ::v-deep.el-tree-node:after { border-top: 1px solid #e5e6eb; height: 10px; top: 10px; width: 14px; transform: rotate(20deg); } ::v-deep .el-tree-node__content { padding-left: 10px !important; } ::v-deep.el-tree-node__expand-icon { position: absolute; right: 2%; } ::v-deep .el-tree-node__content { margin: 10px 0; } }