【Vue】element-ui Tree如何定位到一个节点,并高亮显示该节点?

我要实现的效果是:搜索关键字,得到搜索结果
【Vue】element-ui Tree如何定位到一个节点,并高亮显示该节点?

点击搜索结果,展开节点,并定位到该结果的位置(高亮显示)

目前只实现了展开节点的效果
【Vue】element-ui Tree如何定位到一个节点,并高亮显示该节点?

定位到该结果的位置和高亮显示这两点无法实现

  • 定位到该结果的位置:目前只是展开了节点,并没有定位效果,如果该节点的列表很长,也只会显示上半部分的可视区域,无定位效果,但是不知道如何来写?

  • 高亮显示:我想要最终实现的是下面的图中的效果

【Vue】element-ui Tree如何定位到一个节点,并高亮显示该节点?

并且当结果过长的时,能定位到该节点的位置
【Vue】element-ui Tree如何定位到一个节点,并高亮显示该节点?

回答

搜索到关键字后,设置 element-ui Tree 的 current-node-key 属性,可以设置节点选中,样式可以自己覆盖调整

this.$refs.tree.setCurrentKey(key)没有问题,
但是要正确设置属性node-key="XXX",
名称和类型都需要和要设置的 key 一样

至于滚动,需要计算选中节点到树图顶点的距离,这个需要根据展开情况计算,下面是测试代码,模拟选中然后滚动

【Vue】element-ui Tree如何定位到一个节点,并高亮显示该节点?

做的项目中也遇到过类似的问题,说一下解法。
需求:在搜索框中输入搜索内容,下拉出来的搜索结果中第一个默认高亮显示,点击搜索结果中的其中一个,然后直接跳转到相应的节点位置。
思路: 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

回到顶部