当前位置:首页 > VUE

vue实现目录

2026-03-26 19:01:04VUE

Vue 实现目录功能

在 Vue 中实现目录功能通常涉及动态渲染内容标题、监听滚动位置以及高亮当前章节。以下是常见的实现方法:

动态生成目录结构

使用 v-for 循环渲染标题元素,通过 querySelectorAll 获取页面中的标题标签(如 h2/h3):

<template>
  <div class="toc">
    <div v-for="(item, index) in headings" :key="index" 
         :class="{ active: activeIndex === index }"
         @click="scrollTo(item)">
      {{ item.text }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      headings: [],
      activeIndex: 0
    }
  },
  mounted() {
    this.initHeadings()
    window.addEventListener('scroll', this.onScroll)
  },
  methods: {
    initHeadings() {
      this.headings = Array.from(document.querySelectorAll('h2, h3'))
        .map(el => ({
          text: el.innerText,
          offsetTop: el.offsetTop
        }))
    },
    scrollTo(item) {
      window.scrollTo({
        top: item.offsetTop,
        behavior: 'smooth'
      })
    },
    onScroll() {
      const scrollPosition = window.scrollY
      this.headings.forEach((item, index) => {
        if (item.offsetTop <= scrollPosition + 100) {
          this.activeIndex = index
        }
      })
    }
  }
}
</script>

使用 IntersectionObserver 优化性能

替代滚动事件监听,减少性能消耗:

methods: {
  setupObserver() {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const index = this.headings.findIndex(
            h => h.text === entry.target.innerText
          )
          this.activeIndex = index
        }
      })
    }, { threshold: 0.5 })

    document.querySelectorAll('h2, h3').forEach(el => {
      observer.observe(el)
    })
  }
}

嵌套目录实现

对于多级目录(如 h2+h3 层级),需结构化数据:

computed: {
  nestedHeadings() {
    const result = []
    let currentH2 = null

    this.headings.forEach(item => {
      if (item.tagName === 'H2') {
        currentH2 = { ...item, children: [] }
        result.push(currentH2)
      } else if (currentH2) {
        currentH2.children.push(item)
      }
    })

    return result
  }
}

样式优化

添加基础交互样式:

.toc {
  position: fixed;
  max-height: 100vh;
  overflow-y: auto;
}
.toc div {
  padding: 8px 12px;
  cursor: pointer;
}
.toc div.active {
  color: #42b983;
  font-weight: bold;
}
.toc div.children {
  padding-left: 20px;
  font-size: 0.9em;
}

使用第三方库

如需快速实现,可考虑以下库:

  • vue-toc:自动生成目录组件
  • vue-scrollactive:滚动高亮集成
  • vue-affix:固定侧边栏定位

实现时需注意:

vue实现目录

  • beforeDestroy 中移除事件监听
  • 对于 SSR 场景需做客户端判断
  • 动态内容需使用 nextTick 确保 DOM 更新

标签: 目录vue
分享给朋友:

相关文章

vue   实现单选

vue 实现单选

Vue 实现单选功能 在 Vue 中实现单选功能可以通过多种方式,以下是几种常见的方法: 使用原生 <input type="radio"> 绑定 v-model 通过 v-model…

vue列表实现

vue列表实现

Vue 列表实现方法 使用 v-for 指令 v-for 是 Vue 中用于渲染列表的核心指令,基于数据源动态生成 DOM 元素。语法格式为 item in items 或 (item, index)…

vue实现详情

vue实现详情

Vue 实现详情页的常见方法 使用动态路由 在 Vue Router 中配置动态路由参数,通过 $route.params 获取详情 ID。示例路由配置: { path: '/detail/:i…

vue实现长按

vue实现长按

Vue 实现长按功能的方法 在 Vue 中实现长按功能可以通过原生事件监听或自定义指令完成。以下是几种常见实现方式: 使用原生事件监听 通过 @mousedown 和 @mouseup 或 @tou…

vue实现浮标

vue实现浮标

Vue 实现浮动按钮(浮标) 使用 Vue 实现浮动按钮可以通过多种方式完成,以下是几种常见的方法: 使用 CSS 定位和 Vue 组件 创建 Vue 组件并配合 CSS 固定定位实现浮动按钮:…

vue 实现登录

vue 实现登录

Vue 实现登录功能 创建登录表单组件 在 Vue 项目中创建一个登录表单组件(如 Login.vue),包含用户名和密码输入框以及提交按钮。使用 v-model 实现双向数据绑定。 <tem…