vue实现电梯导航
实现电梯导航的基本思路
电梯导航(Anchor Navigation)是一种常见的页面内快速定位功能,通常用于长页面中快速跳转到指定章节。Vue 实现的核心在于监听滚动事件并动态更新导航状态。
基础实现步骤
HTML 结构

<template>
<div>
<!-- 导航栏 -->
<div class="anchor-nav">
<a
v-for="(item, index) in sections"
:key="index"
:class="{ active: currentSection === index }"
@click="scrollTo(index)"
>
{{ item.title }}
</a>
</div>
<!-- 内容区块 -->
<div
v-for="(item, index) in sections"
:key="index"
:ref="`section-${index}`"
class="content-section"
>
<h2>{{ item.title }}</h2>
<p>{{ item.content }}</p>
</div>
</div>
</template>
JavaScript 逻辑
<script>
export default {
data() {
return {
sections: [
{ title: 'Section 1', content: '...' },
{ title: 'Section 2', content: '...' },
{ title: 'Section 3', content: '...' }
],
currentSection: 0,
observer: null
}
},
mounted() {
this.initIntersectionObserver()
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
if (this.observer) this.observer.disconnect()
window.removeEventListener('scroll', this.handleScroll)
},
methods: {
initIntersectionObserver() {
this.observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const index = this.sections.findIndex(
(_, i) => this.$refs[`section-${i}`][0] === entry.target
)
if (index !== -1) this.currentSection = index
}
})
},
{ threshold: 0.5 }
)
this.sections.forEach((_, index) => {
this.observer.observe(this.$refs[`section-${index}`][0])
})
},
scrollTo(index) {
const element = this.$refs[`section-${index}`][0]
element.scrollIntoView({ behavior: 'smooth' })
},
handleScroll() {
// 备用滚动检测逻辑
}
}
}
</script>
样式优化建议
<style>
.anchor-nav {
position: fixed;
top: 20px;
right: 20px;
background: white;
padding: 10px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.anchor-nav a {
display: block;
padding: 5px 10px;
color: #333;
cursor: pointer;
}
.anchor-nav a.active {
color: #42b983;
font-weight: bold;
}
.content-section {
min-height: 100vh;
padding: 20px;
border-bottom: 1px solid #eee;
}
</style>
高级功能扩展
节流优化 添加 lodash 的节流函数防止滚动事件频繁触发:

import { throttle } from 'lodash'
methods: {
handleScroll: throttle(function() {
// 滚动逻辑
}, 100)
}
动态锚点生成 根据页面内容自动生成导航项:
mounted() {
const headings = document.querySelectorAll('h2, h3')
this.sections = Array.from(headings).map(heading => ({
title: heading.textContent,
id: heading.id || heading.textContent.toLowerCase().replace(/\s+/g, '-')
}))
}
滚动偏移补偿 考虑固定导航栏的高度:
scrollTo(index) {
const element = this.$refs[`section-${index}`][0]
const offset = 80 // 导航栏高度
const bodyRect = document.body.getBoundingClientRect().top
const elementRect = element.getBoundingClientRect().top
const elementPosition = elementRect - bodyRect
const offsetPosition = elementPosition - offset
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
})
}
注意事项
- 使用 IntersectionObserver API 需要兼容性处理,可添加 polyfill
- 移动端需考虑 touch 事件支持
- 对于 SSR 应用需注意客户端特有 API 的使用时机
- 导航栏固定定位可能导致内容遮挡,需预留 padding
以上实现方案结合了现代浏览器 API 和传统滚动检测方法,可根据实际项目需求调整细节。






