You need to enable JavaScript to run this app. Vue中如何通过IntersectionObserver/Scrollspy给对应section导航加自定义激活类
优惠活动
大模型
产品
解决方案
定价
更多

Vue中如何通过IntersectionObserver/Scrollspy给对应section导航加自定义激活类

问题根因

Vue Router默认的router-link-active、router-link-exact-active类是通过匹配路由路径来判定激活状态的,你所有导航链接的路由路径都是/,仅hash锚点不同,因此默认逻辑会把所有同路径的链接都标记为激活,需要自行通过滚动监听来控制激活状态。

解决方案

1. 修改导航模板,绑定动态激活类

放弃依赖Router自带的激活类,自定义激活类,通过变量控制当前激活的导航项:

<template>
  <nav>
    <router-link 
      to="/" 
      :class="{ 'nav-active': currentActive === 'home' }"
    >Home</router-link>
    <router-link 
      to="/#about" 
      :class="{ 'nav-active': currentActive === 'about' }"
    >About</router-link>
    <router-link 
      to="/#contact" 
      :class="{ 'nav-active': currentActive === 'contact' }"
    >Contact</router-link>
  </nav>

  <!-- 你的section代码 -->
  <section id="home">Home</section>
  <section id="about">About</section>
  <section id="contact">Contact</section>
</template>

2. 新增滚动监听逻辑,动态更新激活状态

监听页面滚动事件,判定当前视口内展示的section,更新激活变量:
以下为Vue3 Composition API示例:

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

// 存储当前激活的section id
const currentActive = ref('home')
// 所有需要监听的section id列表
const sectionList = ['home', 'about', 'contact']
// 滚动偏移量,适配固定头部的场景,值和头部高度保持一致即可
const OFFSET = 80

const scrollHandler = () => {
  const scrollY = window.scrollY + OFFSET
  sectionList.forEach(id => {
    const sectionEl = document.getElementById(id)
    if (!sectionEl) return
    const sectionTop = sectionEl.offsetTop
    const sectionHeight = sectionEl.offsetHeight
    // 判定滚动位置是否落在当前section范围内
    if (scrollY >= sectionTop && scrollY < sectionTop + sectionHeight) {
      currentActive.value = id
    }
  })
}

onMounted(() => {
  window.addEventListener('scroll', scrollHandler)
  // 页面初始化/刷新时执行一次,适配直接访问带锚点链接的场景
  scrollHandler()
})

onUnmounted(() => {
  window.removeEventListener('scroll', scrollHandler)
})
</script>

如果你用的是Vue2,把逻辑对应迁移到选项式API的data、mounted、beforeDestroy生命周期即可。

3. 自定义激活类样式

.nav-active {
  color: #3b82f6;
  font-weight: 600;
  border-bottom: 2px solid #3b82f6;
  /* 按需修改你需要的激活样式 */
}

可选优化:配置路由平滑滚动

如果需要点击导航时平滑滚动到对应section,可以在Router配置中新增scrollBehavior配置:

// Vue Router 4.x 示例
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [/* 你的路由配置 */],
  scrollBehavior(to) {
    if (to.hash) {
      return {
        el: to.hash,
        behavior: 'smooth',
        // 偏移量和上面的OFFSET保持一致,适配固定头部
        top: 80
      }
    }
    return { top: 0 }
  }
})

内容的提问来源于stack exchange,提问作者Shubhang Chourasia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 06:24:03