You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Vue.js中使用Lenis时,点击菜单项为何跳转而非平滑滚动?

解决Vue.js中Lenis平滑滚动点击菜单直接跳转的问题

问题描述

在Vue.js项目中使用Lenis库实现平滑滚动,但点击导航菜单项时,页面直接跳转至目标区域,而非执行Lenis的平滑滚动逻辑。HTML环境下通过CDN引入Lenis时功能正常,但Vue项目内无法复现该效果。

问题根源

  1. Lenis实例作用域限制:App.vue中创建的lenis是onMounted函数的局部变量,Header组件的原生onclick无法访问到该实例,导致Lenis的平滑滚动逻辑未触发,反而执行了a标签的默认锚点跳转。
  2. a标签默认行为未阻止:即使Lenis调用成功,a标签的原生跳转行为会直接覆盖平滑滚动效果,必须手动阻止。

修复方案

步骤1:让Header组件能访问到Lenis实例

方式1:全局暴露Lenis实例(快速解决)

修改App.vue的onMounted钩子,将Lenis实例挂载到window对象:

<script setup>
import { onMounted } from "vue";
import Lenis from "@studio-freight/lenis";
// 导入其他组件...

onMounted(() => {
  const lenis = new Lenis();
  // 暴露到全局,让Header组件能访问
  window.lenis = lenis;

  function raf(time) {
    lenis.raf(time);
    requestAnimationFrame(raf);
  }

  requestAnimationFrame(raf);
});
</script>

方式2:使用Vue Provide/Inject传递实例(更优雅)

避免全局变量污染,用Vue的依赖传递机制:

  1. 在App.vue中提供实例:
<script setup>
import { onMounted, provide } from "vue";
import Lenis from "@studio-freight/lenis";
// 导入其他组件...

onMounted(() => {
  const lenis = new Lenis();
  // 提供给子组件
  provide('lenis', lenis);

  function raf(time) {
    lenis.raf(time);
    requestAnimationFrame(raf);
  }

  requestAnimationFrame(raf);
});
</script>
  1. 在Header组件中注入并使用:
<script setup>
import { ref, inject } from "vue";
const isActive = ref(false);
const lenis = inject('lenis');

function deactive() {
  isActive.value = false;
}

// 封装滚动方法
const scrollToSection = (target) => {
  lenis?.scrollTo(target);
}
</script>

步骤2:阻止a标签的默认跳转行为

替换原生onclick为Vue事件处理,同时阻止默认行为:

针对全局暴露的实例:

<!-- 桌面端导航 -->
<nav class="hidden w-1/3 items-center justify-end gap-6 bg-gradient-to-r from-fuchsia-400 to-pink-600 bg-clip-text text-lg font-semibold text-transparent lg:flex">
  <a href="#stack" @click.prevent="window.lenis.scrollTo('#stack')">Stack</a>
  <a href="#projects" @click.prevent="window.lenis.scrollTo('#projects')">Projects</a>
  <a href="#contact" @click.prevent="window.lenis.scrollTo('#contact')"> Let's Talk </a>
</nav>

<!-- 移动端菜单示例 -->
<a
  @click="deactive; window.lenis.scrollTo('#stack')"
  href="#stack"
  @click.prevent
  class="group relative h-full w-full"
>
<!-- 其余移动端a标签同理修改 -->

针对Provide/Inject的方式:

<!-- 桌面端导航 -->
<nav class="hidden w-1/3 items-center justify-end gap-6 bg-gradient-to-r from-fuchsia-400 to-pink-600 bg-clip-text text-lg font-semibold text-transparent lg:flex">
  <a href="#stack" @click.prevent="scrollToSection('#stack')">Stack</a>
  <a href="#projects" @click.prevent="scrollToSection('#projects')">Projects</a>
  <a href="#contact" @click.prevent="scrollToSection('#contact')"> Let's Talk </a>
</nav>

<!-- 移动端菜单示例 -->
<a
  @click="deactive; scrollToSection('#stack')"
  href="#stack"
  @click.prevent
  class="group relative h-full w-full"
>
<!-- 其余移动端a标签同理修改 -->

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:08:10