vue实现左右楼层跳转
实现思路
通过监听滚动事件,计算各楼层元素的位置信息,实现点击左侧导航跳转对应楼层,同时滚动时自动高亮当前所在楼层的导航项。
核心代码实现
<template>
<div class="container">
<div class="left-nav">
<ul>
<li
v-for="(item, index) in floors"
:key="index"
:class="{ active: currentFloor === index }"
@click="scrollToFloor(index)"
>
{{ item.name }}
</li>
</ul>
</div>
<div class="right-content">
<div
v-for="(item, index) in floors"
:key="index"
:ref="'floor' + index"
class="floor-item"
>
{{ item.content }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
floors: [
{ name: '楼层1', content: '内容1' },
{ name: '楼层2', content: '内容2' },
{ name: '楼层3', content: '内容3' }
],
currentFloor: 0,
floorPositions: []
}
},
mounted() {
this.calcFloorPositions()
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
},
methods: {
calcFloorPositions() {
this.floorPositions = this.floors.map((_, index) => {
return this.$refs['floor' + index][0].offsetTop
})
},
scrollToFloor(index) {
window.scrollTo({
top: this.floorPositions[index],
behavior: 'smooth'
})
},
handleScroll() {
const scrollPosition = window.scrollY + 100
for (let i = 0; i < this.floorPositions.length; i++) {
if (
scrollPosition >= this.floorPositions[i] &&
(i === this.floorPositions.length - 1 ||
scrollPosition < this.floorPositions[i + 1])
) {
this.currentFloor = i
break
}
}
}
}
}
</script>
<style>
.container {
display: flex;
}
.left-nav {
position: fixed;
width: 200px;
}
.right-content {
margin-left: 220px;
width: calc(100% - 220px);
}
.floor-item {
height: 800px;
margin-bottom: 20px;
background: #f5f5f5;
}
.active {
color: red;
font-weight: bold;
}
</style>
实现要点
-
数据结构设计
使用floors数组存储各楼层信息,包含名称和内容。
-
位置计算
在mounted钩子中调用calcFloorPositions方法,通过ref获取各楼层DOM元素的offsetTop值。 -
滚动监听
添加scroll事件监听器,实时计算当前滚动位置对应的楼层索引。
-
平滑滚动
使用window.scrollTo方法实现平滑滚动效果,通过behavior: 'smooth'参数。 -
响应式样式
通过currentFloor数据绑定动态设置导航项的高亮样式。
优化建议
- 添加防抖处理优化scroll事件性能
- 考虑使用Intersection Observer API替代scroll事件监听
- 对于动态内容,需要在内容更新后重新计算楼层位置
- 移动端适配时可考虑将导航改为横向滚动式






