vue实现楼梯效果
Vue实现楼梯效果
楼梯效果通常指页面滚动时,侧边栏或导航栏根据滚动位置高亮对应的章节标题。以下是实现方法:

使用Intersection Observer API
Intersection Observer API可以监听元素是否进入视口,适合实现楼梯效果。

<template>
<div>
<div class="content" v-for="(item, index) in sections" :id="`section-${index}`">
{{ item }}
</div>
<div class="stair-nav">
<div
v-for="(item, index) in sections"
:class="{ active: activeIndex === index }"
@click="scrollTo(index)"
>
{{ item }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
sections: ['Section 1', 'Section 2', 'Section 3'],
activeIndex: 0,
observer: null
}
},
mounted() {
this.initObserver()
},
methods: {
initObserver() {
const options = {
root: null,
rootMargin: '0px',
threshold: 0.5
}
this.observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.id
this.activeIndex = parseInt(id.split('-')[1])
}
})
}, options)
this.sections.forEach((_, index) => {
const element = document.getElementById(`section-${index}`)
this.observer.observe(element)
})
},
scrollTo(index) {
const element = document.getElementById(`section-${index}`)
element.scrollIntoView({ behavior: 'smooth' })
}
},
beforeDestroy() {
this.observer.disconnect()
}
}
</script>
<style>
.stair-nav {
position: fixed;
right: 20px;
top: 50%;
transform: translateY(-50%);
}
.stair-nav div {
padding: 10px;
cursor: pointer;
}
.stair-nav div.active {
color: red;
font-weight: bold;
}
.content {
height: 100vh;
padding: 20px;
}
</style>
使用scroll事件监听
另一种传统方法是监听scroll事件,计算各个section的位置。
<template>
<!-- 同上 -->
</template>
<script>
export default {
data() {
return {
sections: ['Section 1', 'Section 2', 'Section 3'],
activeIndex: 0,
sectionPositions: []
}
},
mounted() {
this.calculatePositions()
window.addEventListener('scroll', this.handleScroll)
},
methods: {
calculatePositions() {
this.sectionPositions = this.sections.map((_, index) => {
const element = document.getElementById(`section-${index}`)
return element.offsetTop
})
},
handleScroll() {
const scrollPosition = window.scrollY + 100
for (let i = 0; i < this.sectionPositions.length; i++) {
if (
scrollPosition >= this.sectionPositions[i] &&
(i === this.sectionPositions.length - 1 ||
scrollPosition < this.sectionPositions[i + 1])
) {
this.activeIndex = i
break
}
}
},
scrollTo(index) {
window.scrollTo({
top: this.sectionPositions[index],
behavior: 'smooth'
})
}
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
}
}
</script>
使用第三方库
vue-scrollactive是一个专门实现此效果的库:
import VueScrollactive from 'vue-scrollactive'
Vue.use(VueScrollactive)
<template>
<div>
<div v-scrollactive v-for="(item, index) in sections" :id="`section-${index}`">
{{ item }}
</div>
<div class="stair-nav">
<a
v-for="(item, index) in sections"
href=`#section-${index}`
class="scrollactive-item"
>
{{ item }}
</a>
</div>
</div>
</template>
注意事项
- Intersection Observer API性能更好,推荐使用
- 对于动态内容,需要在内容变化后重新计算位置
- 移动端需要考虑视口高度和滚动行为差异
- 添加防抖优化scroll事件性能
以上方法均可实现楼梯导航效果,根据项目需求选择合适方案。Intersection Observer API是现代浏览器推荐的方式,第三方库则提供更简单的集成方案。






