vue实现文章目录
Vue 实现文章目录的方法
使用插件自动生成目录
安装 vue-toc 插件:
npm install vue-toc --save
在组件中引入并使用:
<template>
<div>
<vue-toc :content="articleContent" />
<div v-html="articleContent"></div>
</div>
</template>
<script>
import VueToc from 'vue-toc'
export default {
components: { VueToc },
data() {
return {
articleContent: '<h1>标题1</h1><h2>子标题1</h2><h3>三级标题</h3>'
}
}
}
</script>
手动实现目录组件
创建 TableOfContents.vue 组件:
<template>
<div class="toc">
<ul>
<li v-for="(item, index) in headings" :key="index">
<a :href="`#${item.id}`">{{ item.text }}</a>
</li>
</ul>
</div>
</template>
<script>
export default {
props: ['headings'],
mounted() {
this.generateHeadings()
},
methods: {
generateHeadings() {
const article = document.querySelector('.article-content')
const headings = article.querySelectorAll('h1, h2, h3, h4, h5, h6')
this.headings = Array.from(headings).map(heading => ({
id: heading.id || heading.textContent.toLowerCase().replace(/\s+/g, '-'),
text: heading.textContent,
level: parseInt(heading.tagName.substring(1))
}))
}
}
}
</script>
动态高亮当前阅读位置
添加滚动监听:
methods: {
handleScroll() {
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
let currentHeading = null
headings.forEach(heading => {
const rect = heading.getBoundingClientRect()
if (rect.top >= 0 && rect.top < 200) {
currentHeading = heading
}
})
if (currentHeading) {
// 更新活动目录项样式
this.activeId = currentHeading.id
}
}
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
}
平滑滚动到锚点
添加平滑滚动效果:
methods: {
scrollToHeading(id) {
const element = document.getElementById(id)
if (element) {
window.scrollTo({
top: element.offsetTop - 20,
behavior: 'smooth'
})
}
}
}
样式优化
添加基本样式:
.toc {
position: fixed;
top: 20px;
right: 20px;
max-width: 300px;
padding: 10px;
background: #f8f8f8;
border-radius: 4px;
}
.toc ul {
list-style: none;
padding-left: 0;
}
.toc li {
margin: 5px 0;
padding-left: calc((var(--level) - 1) * 15px);
}
.toc a {
color: #333;
text-decoration: none;
}
.toc a:hover, .toc .active {
color: #42b983;
font-weight: bold;
}
响应式设计
添加媒体查询适应移动设备:
@media (max-width: 768px) {
.toc {
position: static;
max-width: 100%;
margin-bottom: 20px;
}
}




