vue3实现目录
Vue3 实现目录功能
在Vue3中实现目录功能通常涉及动态渲染页面结构、滚动监听和锚点跳转。以下是具体实现方法:

动态生成目录结构
使用ref和v-for动态渲染目录项,基于页面内容提取标题(如h2/h3标签):

const headings = ref([])
onMounted(() => {
const elements = document.querySelectorAll('h2, h3')
headings.value = Array.from(elements).map(el => ({
id: el.id || generateId(),
text: el.textContent,
level: parseInt(el.tagName.substring(1))
}))
})
滚动高亮当前章节
结合Intersection Observer API实现滚动高亮:
const activeId = ref(null)
onMounted(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
activeId.value = entry.target.id
}
})
},
{ rootMargin: '0px 0px -80% 0px' }
)
headings.value.forEach(({ id }) => {
const element = document.getElementById(id)
if (element) observer.observe(element)
})
})
样式处理
为不同级别标题添加缩进样式:
.toc-item {
padding-left: calc(var(--level) * 12px);
&.active {
color: var(--primary-color);
font-weight: bold;
}
}
完整组件示例
<template>
<div class="toc-container">
<div
v-for="item in headings"
:key="item.id"
:class="['toc-item', { active: activeId === item.id }]"
:style="{ '--level': item.level - 1 }"
@click="scrollTo(item.id)"
>
{{ item.text }}
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const headings = ref([])
const activeId = ref(null)
const scrollTo = (id) => {
const element = document.getElementById(id)
element?.scrollIntoView({ behavior: 'smooth' })
}
onMounted(() => {
// 初始化目录和观察者逻辑
})
</script>
优化建议
- 添加防抖处理滚动事件
- 对于大型文档考虑虚拟滚动
- 支持可折叠的嵌套目录结构
- 添加平滑滚动动画
- 考虑使用Vue Router的hash模式兼容性
实现时需根据实际项目需求调整细节,如标题选择器、滚动偏移量等参数。






