vue实现目录
Vue 实现目录功能
在 Vue 中实现目录功能通常需要动态生成目录结构,并支持点击跳转到对应内容区域。以下是几种常见实现方式:
基于滚动监听和动态生成
安装依赖(如需):
npm install vue-scrollto
组件实现:
<template>
<div>
<div class="toc" v-if="headings.length">
<ul>
<li v-for="(heading, index) in headings" :key="index">
<a @click="scrollTo(heading.id)">{{ heading.text }}</a>
</li>
</ul>
</div>
<div class="content" v-html="content" ref="content"></div>
</div>
</template>
<script>
import VueScrollTo from 'vue-scrollto'
export default {
data() {
return {
headings: [],
content: '<h1 id="section1">Section 1</h1><p>Content...</p><h2 id="section2">Section 2</h2><p>More content...</p>'
}
},
mounted() {
this.generateTOC()
},
methods: {
generateTOC() {
const contentEl = this.$refs.content
const headingEls = contentEl.querySelectorAll('h1, h2, h3, h4, h5, h6')
this.headings = Array.from(headingEls).map(el => ({
id: el.id,
text: el.innerText,
level: parseInt(el.tagName.substring(1))
}))
},
scrollTo(id) {
VueScrollTo.scrollTo(`#${id}`, 500)
}
}
}
</script>
<style>
.toc {
position: fixed;
right: 20px;
top: 20px;
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
}
.toc ul {
list-style: none;
padding: 0;
margin: 0;
}
.toc li {
margin: 5px 0;
}
.toc a {
cursor: pointer;
color: #333;
}
.toc a:hover {
text-decoration: underline;
}
</style>
使用第三方库
对于更复杂的需求,可以使用专门库如 vue-toc:

安装:
npm install vue-toc
使用示例:

<template>
<div>
<vue-toc :content="content" />
<div v-html="content"></div>
</div>
</template>
<script>
import VueToc from 'vue-toc'
export default {
components: { VueToc },
data() {
return {
content: '<h1>Title</h1><h2>Subtitle</h2><p>Content...</p>'
}
}
}
</script>
动态路由目录
对于多页面应用的目录,可以结合 Vue Router:
<template>
<div>
<ul>
<li v-for="item in menuItems" :key="item.path">
<router-link :to="item.path">{{ item.title }}</router-link>
</li>
</ul>
<router-view />
</div>
</template>
<script>
export default {
data() {
return {
menuItems: [
{ path: '/section1', title: 'Section 1' },
{ path: '/section2', title: 'Section 2' }
]
}
}
}
</script>
响应式目录高亮
添加滚动监听实现当前目录项高亮:
mounted() {
window.addEventListener('scroll', this.onScroll)
},
methods: {
onScroll() {
const headings = document.querySelectorAll('h1, h2, h3')
let current = ''
headings.forEach(heading => {
const rect = heading.getBoundingClientRect()
if (rect.top <= 100) {
current = heading.id
}
})
this.activeHeading = current
}
}
模板中添加高亮类:
<li v-for="heading in headings" :class="{ active: activeHeading === heading.id }">
<a @click="scrollTo(heading.id)">{{ heading.text }}</a>
</li>
以上方法可根据具体需求选择或组合使用。对于内容动态加载的情况,需要在内容更新后重新调用 generateTOC 方法。






