在Web应用程序中,提供一个锚点导航系统可以帮助用户快速导航到页面的不同部分。这在处理长页面时尤其有用。在Vue3中,我们可以利用Composition API和一些简单的JavaScript来实现这样一个系统。下面是如何做到这一点的步骤。

PS:使用 Ant Design for Vue v3.2.20,但原锚点组件无法在哈希路由应用内和Dialog组件内正常使用,于是有了本篇的方法来解决这些问题。

页面结构

我们的页面包含一个包装了锚点的容器和两个表格,每个表格都有一个唯一的ID,用户可以点击锚点链接在这些表格之间跳转。

<div class="guwave-anchor-wrapper">
  <a-anchor affix wrapper-class="guwave-anchor" @click="handleAnchorClick" :getContainer="getContainer" :getCurrentAnchor="getCurrentAnchor">
    <a-anchor-link v-for="link in anchorLinks" :href="link.href" :title="link.title" />
  </a-anchor>
</div>

<div id="table-A"></div>
<!-- 表格A的内容... -->

<div id="table-B"></div>
<!-- 表格B的内容... -->

功能逻辑

首先,我们设置一个ref来引用我们的主容器元素,并定义了一个包含锚点信息的数组。

const mainRef = ref();
const anchorLinks = [
  {
    href: 'table-A',
    title: '表格A'
  },
  {
    href: 'table-B',
    title: '表格B'
  }
];
function getContainer() {
  return mainRef.value;
}

获取当前锚点

getCurrentAnchor函数计算哪个锚点距离滚动容器顶部最近,并返回其href。

function getCurrentAnchor() {
  if (!mainRef || !mainRef.value || !anchorLinks || anchorLinks.length === 0) {
    return null;
  }

  let currentAnchorHref = null;
  let closestDistance = Infinity;

  // 遍历每个锚点链接
  anchorLinks.forEach((anchorLink) => {
    const anchorId = anchorLink.href; // 假设href就是锚点的ID
    const anchorElement = mainRef.value.querySelector(`#${anchorId}`);

    // 计算锚点元素的顶部和mainRef元素的滚动顶部之间的距离
    if (anchorElement) {
      const distance = Math.abs(anchorElement.offsetTop - mainRef.value.scrollTop);

      // 如果这个距离比之前找到的距离还要小,那么更新当前锚点
      if (distance < closestDistance) {
        closestDistance = distance;
        currentAnchorHref = anchorLink.href;
      }
    }
  });

  // 返回最接近的锚点的href
  return currentAnchorHref;
}

处理锚点点击

点击事件被handleAnchorClick函数处理,它阻止默认行为,并平滑滚动到目标锚点。

function handleAnchorClick(e, link) {
  e.preventDefault();
  const toId = link.href;
  const to = document.getElementById(toId);
  to.scrollIntoView({ block: 'start', behavior: 'smooth' });
}

完整的Vue组件

将所有这些整合起来,我们得到了一个功能完整的锚点滚动导航系统。

<template>
  <!-- ...模板内容... -->
</template>

<script setup>
// ...导入的模块和定义的逻辑...
</script>

<style>
/* ...样式内容... */
</style>

结论

通过上述步骤,我们可以在Vue3应用程序中实现一个响应式的锚点滚动导航系统,增强用户的页面导航体验。这个系统利用了Vue3的响应性和组件化特性,以及原生JavaScript的强大功能。


A Student on the way to full stack of Web3.