【Vue】element-ui Tree如何定位到一个节点,并高亮显示该节点?
我要实现的效果是:搜索关键字,得到搜索结果
点击搜索结果,展开节点,并定位到该结果的位置(高亮显示)
目前只实现了展开节点的效果
定位到该结果的位置和高亮显示这两点无法实现
定位到该结果的位置:目前只是展开了节点,并没有定位效果,如果该节点的列表很长,也只会显示上半部分的可视区域,无定位效果,但是不知道如何来写?
- 高亮显示:我想要最终实现的是下面的图中的效果
并且当结果过长的时,能定位到该节点的位置
回答
搜索到关键字后,设置 element-ui Tree 的 current-node-key 属性,可以设置节点选中,样式可以自己覆盖调整
this.$refs.tree.setCurrentKey(key)没有问题,
但是要正确设置属性node-key="XXX",
名称和类型都需要和要设置的 key 一样
至于滚动,需要计算选中节点到树图顶点的距离,这个需要根据展开情况计算,下面是测试代码,模拟选中然后滚动
做的项目中也遇到过类似的问题,说一下解法。
需求:在搜索框中输入搜索内容,下拉出来的搜索结果中第一个默认高亮显示,点击搜索结果中的其中一个,然后直接跳转到相应的节点位置。
思路: 1.使用el-tree 2.监听filter,当filter变化的时候,获取class为‘.el-tree-node__children’的第一个标签,然后遍历他的children,如果children中有一个元素的className中不含有is-hidden的则该标签为搜索结果的第一个选项,此时设置他的style。
3.点击某个搜索结果的时候,此时跟2一样,也是获取class为‘.el-tree-node__children’的第一个标签,但是此时遍历children的时候选择的是将所有不含有is-hidden的标签的样式恢复。接着,获取点击的元素,并使用element.scrollIntoView({block: 'end', behavior: 'smooth'})来滚动到点击的位置.
附上相关代码(省略部分的,仅供参考,不一定符合你的需求,拒绝伸手党):
`
<el-input size="mini" class="search" placeholder="请输入节点搜索" v-model="filterText" clearable></el-input><el-tree
ref="baseTree"
...
:filter-node-method="filterNode"
@node-click="handleNodeClick"
></el-tree>
watch: {
filterText(val) {
this.isScroll = true
this.$refs.baseTree.filter(val)
if (val) {
setTimeout(_ => {
this.setSearchResultClass(val)
},500)
}
},
// 设置搜索结果样式
setSearchResultClass () {
let that = this
// 搜寻结果的第一个高亮显示
let parent = document.querySelector('.el-tree-node__children')
let array = parent.children
for (let i = 0; i < array.length; i++) {
let element = array[i]
if (element.className.indexOf('is-hidden') === -1) {
// debugger
if (element.className.indexOf('s-c') === -1 && that.filterText) {
element.className += ' s-c'
return
} else {
element.className -= ' s-c'
}
}
}
}
handleNodeClick(data, node) {
let that = this
this.clickNode = data
that.$emit("on-node-click", data);
// 根据主题色变换树的颜色
that.changeTreeAboutTheme();
// 如果存在搜索,点击节点的时候清空搜索内容且将搜索结果颜色恢复
if (that.filterText) {
that.filterText = ''
that.setSearchResultClass()
}
},
// 根据主题色变换树的颜色
changeTreeAboutTheme() {
let that = this;
that.$nextTick(function () {
let array = document.querySelectorAll('.is-current');
if (array && array.length > 0) {
......
if (that.isScroll) {
element.scrollIntoView({block: 'end', behavior: 'smooth'})
that.isScroll = !that.isScroll
}
}
}
}
})
`
这两天正好在写这个功能,搜集到这里来了,贴出我的代码,希望可以为遇到这个问题的朋友提供参考。
我写的比较复杂,请网友多多指教
首先我用的是一次性加载,不是懒加载。
这段代码里还有折叠其他节点的代码,可以忽略。
图片为啥插不进来。。。第一次写这个,不会搞。。
`
<div id="heheda" style="height: 700px;overflow: auto;"> <el-tree id="heheda1"
v-loading="loading"
:data="videoData"
:props="props"
:allow-drag="allowDrag"
:empty-text="emptyTips"
draggable
accordion
:highlight-current="highLight"
node-key="deviceid"
:default-expanded-keys="expandedKeys"
:current-node-key="currentNode"
ref="videoTree"
>
<span slot-scope="{node, data}">
<svg v-if="data.children == null && data.status == 'ON'" aria-hidden="true"
class="site-sidebar__menu-icon icon-svg icon-svg__menu camera_icon1">
</svg>
<svg v-if="data.children == null && data.status == 'OFF'" aria-hidden="true"
class="site-sidebar__menu-icon icon-svg icon-svg__menu camera_icon2">
</svg>
{{node.label}}
</span>
</el-tree>
</div>
`
videoTree这棵树是默认展开第一个节点的,
selectCamera(camera)方法是点击搜索节点结果的方法,入参是点击的节点结果对象。
下面用到的camera.deviceid就是node-key。
主要逻辑就是,当前只有这一个节点的路径是展开的,
计算出所有展开显示的节点数量nodeCount,
计算出,从根节点开始数,当前节点处于第几个nodeIndex,
已知我的树每个节点高度是26px,故树总高度为26*nodeCount px,
设置树的高度,dom1.style.height = (nodeCount * nodeHight) + "px",
这一步是关键,设置树高,外层DIV的scrollHeight才会变化,
后面代码就写的比较清楚了。
`
selectCamera(camera) { //在这次选中节点之前被选中的节点
let lastNode = this.$refs.videoTree.getNode(this.$refs.videoTree.getCurrentNode())
//这次选中的节点
let currentNode = this.$refs.videoTree.getNode(camera.deviceid)
//收起之前因选中而展开的节点
if (1 != lastNode.level) {
let parentLevel
do {
lastNode.expanded = false
lastNode = lastNode.parent
parentLevel = lastNode.level
}
while (1 != parentLevel)
}
let parentLevel
let nodeCount = 1//当前树展开节点的数量
let nodeIndex = 1//当前选中节点在当前树的位置
let currentNodeName = currentNode.data.name
//计算nodeCount和nodeIndex
do {
currentNode = currentNode.parent
parentLevel = currentNode.level
let childNodes = currentNode.childNodes
nodeCount += childNodes.length
for (let i = 0; i < childNodes.length; i ++) {
if (childNodes[i].data.name == currentNodeName) {
nodeIndex += (i + 1)
}
}
currentNodeName = currentNode.data.name
}
while (1 != parentLevel)
this.expandedKeys = [camera.deviceid]
this.visible = false//可以忽略,与题主功能无关
//设置选中,配置highlight-current后,即可高亮
this.$refs.videoTree.setCurrentKey(camera.deviceid)
let dom = document.querySelector("#heheda")
let dom1 = document.querySelector("#heheda1")
//一个节点的高度是26px,这个值能否从对象中获取,等我把这个功能做好再考虑吧
let nodeHight = 26
dom1.style.height = (nodeCount * nodeHight) + "px"
// 13是因为,div高度为700像素,nodeHight*27=702,略超过700,
// 又因为,div高度是700像素,要使被选中的节点显示在div可视区域的中间,
// 所以就要将27折半,后一半节点要参与滚动条的位移
// 计算位移距离时,减350的原因也是一样,要使被选中的节点显示在div可视区域的中间,就要减去div高度的一半
if (13 < nodeIndex) {
dom.scrollTo(0, (nodeIndex * nodeHight) - 350)
} else {
dom.scrollTo(0, 0)
}
}
`
以上是 【Vue】element-ui Tree如何定位到一个节点,并高亮显示该节点? 的全部内容, 来源链接: utcz.com/a/76627.html