Skip to content

Anchor 锚点导航

页内跳转与滚动高亮。支持自定义滚动容器。

基础用法

下面这个区块内部可以滚动,右侧锚点会跟着高亮当前阅读位置

第一节 · 基础概念

向下滚动,观察右侧锚点的高亮变化。

第二节 · 进阶用法

高亮跟随滚动位置自动切换。

2.1 配置项

子级锚点也会被正确识别。

2.2 最佳实践

当前可见的标题会高亮。

第三节 · 常见问题

滚到底部,最后一个锚点高亮。

<SrAnchor :items="items" :container="`#${containerId}`" :offset="8" />
vue
<template>
  <div id="my-scroll" style="height: 400px; overflow-y: auto">
    <h2 id="section-1">第一节</h2>
    <p>…</p>
    <h2 id="section-2">第二节</h2>
  </div>

  <SrAnchor :items="items" container="#my-scroll" :offset="8" />
</template>

<script setup>
const items = [
  { href: 'section-1', title: '第一节' },
  {
    href: 'section-2',
    title: '第二节',
    children: [{ href: 'section-2-1', title: '2.1 小节' }]
  }
]
</script>

id 找目标

href 对应页面上元素的 id(不含 #)。组件用 document.getElementById() 查找,因此它必须是真实存在的 id。

href 不是链接地址

它不参与路由,只是一个定位标识。写成 '/docs#section' 是找不到的—— 必须就是那个元素的 id 本身。

自定义滚动容器

container 传 CSS 选择器,用于页面内某个可滚动区域

不传时以整个窗口为滚动容器——适合整页的文档站。

vue
<!-- 监听整个窗口(默认) -->
<SrAnchor :items="items" />

<!-- 监听指定容器 -->
<SrAnchor :items="items" container="#my-scroll" />

<!-- 监听某个特定元素下的容器 -->
<SrAnchor :items="items" container=".docs-content" />

关键:高亮范围限定在容器内

组件只会考虑容器内部的标题。因此页面其他区域(比如顶部导航里也有 一个同名的 h2)不会干扰高亮判断。

这也是为什么传 container 比「整页模式」更稳——它把关注范围收窄了。

偏移量

offset 是「判定线下移的距离」,通常等于吸顶头部的高度

有固定头部时,标题滚到视口顶部会被头部挡住。把 offset 设成头部高度, 高亮会在标题完全露出时才切换,而不是刚碰到视口边缘就切。

offset=8(贴合容器内边距)· bounds 控制提前量 · smooth 控制是否平滑滚动

vue
<SrAnchor :items="items" :offset="64" :bounds="6" smooth />
参数作用
offset判定线下移多少像素(通常设为吸顶头高度)
bounds提前量——标题距判定线还有多少像素时就切换高亮
smooth点击时是否平滑滚动(系统开启「减少动态效果」时自动关闭)

高亮样式

vue
<SrAnchor variant="line" />
<SrAnchor variant="block" />
<SrAnchor variant="dot" />
变体视觉
line左侧竖线,当前项高亮(默认)
block当前项整块着色
dot左侧圆点标记当前位置

层级缩进

indent 控制子级缩进,showLine 是否显示连接线。

vue
<SrAnchor :items="items" :indent="20" show-line />

数据结构

ts
interface SrAnchorLink {
  href: string          // 目标元素的 id(不含 #)
  title: string         // 显示文本
  children?: SrAnchorLink[]  // 子项,用于表达标题层级
}

Props

名称类型默认值说明
itemsSrAnchorLink[][]锚点列表
containerstring滚动容器的 CSS 选择器;不传则监听窗口
offsetnumber0判定线下移距离(px),通常设为吸顶头高度
boundsnumber5高亮切换的提前量(px)
smoothbooleantrue点击时是否平滑滚动
variant'line' | 'block' | 'dot''line'高亮样式
showLinebooleanfalse是否显示层级连接线
indentnumber16子级缩进(px)

事件

事件参数说明
changehref当前高亮的锚点变化

无障碍

  • <nav> 语义,当前项带 aria-current="location"
  • 锚点是 <a href="#id">键盘可直接跳转, 且不依赖 JS(scroll-behavior 由 CSS 处理降级)
  • smooth 会尊重 prefers-reduced-motion:系统开启「减少动态效果」时 自动改为瞬时跳转——长时间的平滑滚动对前庭敏感人群很不友好

自用组件库 · 源码分发 · 不发布 npm