Nuxt3中实现锚点链接平滑滚动的最佳方案
Nuxt3 实现锚点平滑滚动最优方案
第三方Vue3平滑滚动包无法在Nuxt3运行的核心原因是大多没有做SSR适配,在服务端渲染阶段直接访问浏览器DOM对象导致报错,同时也没有对齐Nuxt的路由生命周期。完全不需要额外引入第三方依赖,用Nuxt原生能力就能实现和react-anchor-link-smooth-scroll完全一致的效果,性能更好兼容性也更强。
方案1:全局原生配置(零代码侵入,优先推荐)
这个方案不需要写自定义滚动逻辑,通过Nuxt路由配置+CSS兜底实现全场景平滑滚动,和第三方包核心能力完全对齐:
- 第一步:在
nuxt.config.ts中覆盖默认滚动行为,配置锚点平滑滚动规则
export default defineNuxtConfig({ app: { // 自定义滚动逻辑 scrollBehavior(to, from, savedPosition) { // 路由带hash锚点时触发平滑滚动 if (to.hash) { return { el: to.hash, behavior: 'smooth', // 配置全局固定偏移量,适配顶部固定导航栏,对应react-anchor-link-smooth-scroll的offset参数 top: 80 } } // 常规页面跳转回到顶部 return { top: 0 } } } })
- 第二步:添加CSS全局兜底,兼容直接访问带hash链接、局部锚点跳转等场景,在全局样式文件(如
assets/css/global.css)中添加:
html { scroll-behavior: smooth; } /* 锚点元素滚动偏移兜底,避免内容被固定导航栏遮挡 */ :target { scroll-margin-top: 80px; }
- 使用方式和普通锚点完全一致,不需要引入额外组件:
<template> <!-- 导航锚点链接 --> <a href="#section1">跳转到第一区块</a> <!-- 目标锚点元素 --> <section id="section1">第一区块内容</section> </template>
该方案完全兼容Nuxt3的SSR/SSG渲染模式,不会出现服务端运行报错,点击锚点、直接访问带hash的URL、浏览器前进后退操作都能正常触发平滑滚动,偏移量支持全局自定义。
方案2:自定义可复用AnchorLink组件(需要灵活配置时使用)
如果你需要和react-anchor-link-smooth-scroll一样支持单链接自定义偏移、点击回调等个性化能力,可以自行封装轻量组件,代码量极小且完全适配Nuxt3:
- 新建
components/AnchorLink.vue组件,Nuxt会自动全局注册,不需要手动引入:
<template> <a :href="`#${to}`" @click.prevent="handleSmoothScroll" v-bind="$attrs" > <slot /> </a> </template> <script setup lang="ts"> const props = defineProps<{ to: string offset?: number // 单链接自定义偏移量,优先级高于全局配置 }>() const handleSmoothScroll = () => { // 服务端环境直接返回,避免DOM访问报错 if (import.meta.server) return const targetEl = document.querySelector(`#${props.to}`) if (!targetEl) return // 计算准确滚动位置 const scrollTarget = targetEl.getBoundingClientRect().top + window.scrollY - (props.offset ?? 80) window.scrollTo({ top: scrollTarget, behavior: 'smooth' }) // 更新地址栏hash,不触发页面刷新 history.pushState(null, '', `#${props.to}`) } </script>
- 组件使用方式:
<template> <!-- 使用全局默认偏移量 --> <AnchorLink to="section2">跳转到第二区块</AnchorLink> <!-- 单独为该链接设置120px偏移 --> <AnchorLink to="section3" :offset="120">跳转到第三区块</AnchorLink> </template>
常见问题规避
- 不要直接使用未标注Nuxt3适配的Vue生态平滑滚动包,这类包大多在setup初始化阶段直接访问
window/document对象,会导致SSR阶段直接抛出异常 - 如果锚点元素是接口请求返回后才异步渲染的,可以在全局
scrollBehavior逻辑中添加100ms左右的延迟,等DOM渲染完成后再执行滚动,避免找不到目标元素 - 如果项目配置了页面过渡动画,建议将滚动逻辑绑定到过渡结束钩子后执行,避免DOM位置未稳定导致滚动位置计算偏差
内容的提问来源于stack exchange,提问作者user19223775
相关产品推荐
相关产品推荐

