vue 实现目录
实现目录功能的基本思路
在Vue中实现目录功能通常需要动态生成基于页面内容或路由结构的目录列表。目录可以用于导航、快速跳转或展示内容结构。
基于路由的目录实现
通过Vue Router的路由配置自动生成目录结构:
// 在组件中
export default {
computed: {
menuItems() {
return this.$router.options.routes.filter(route => {
return route.meta && route.meta.showInMenu
})
}
}
}
基于页面标题的目录实现
扫描页面中的标题元素(h1-h6)生成目录:
mounted() {
this.generateToc()
},
methods: {
generateToc() {
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
this.tocItems = Array.from(headings).map(heading => ({
id: heading.id || heading.textContent.toLowerCase().replace(/\s+/g, '-'),
text: heading.textContent,
level: parseInt(heading.tagName.substring(1))
}))
}
}
目录组件示例
创建一个可复用的目录组件:
<template>
<div class="toc-container">
<ul>
<li v-for="item in items" :key="item.id" :class="`level-${item.level}`">
<a :href="`#${item.id}`">{{ item.text }}</a>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
items: {
type: Array,
required: true
}
}
}
</script>
<style>
.toc-container {
position: fixed;
right: 20px;
top: 20px;
}
.level-1 { font-weight: bold; }
.level-2 { padding-left: 1em; }
.level-3 { padding-left: 2em; }
</style>
平滑滚动实现
为目录链接添加平滑滚动效果:
methods: {
smoothScroll(e) {
e.preventDefault()
const targetId = e.target.getAttribute('href').substring(1)
const targetElement = document.getElementById(targetId)
if (targetElement) {
targetElement.scrollIntoView({
behavior: 'smooth'
})
}
}
}
动态高亮当前章节
监听滚动事件高亮当前可见的章节:
data() {
return {
activeItem: null
}
},
mounted() {
window.addEventListener('scroll', this.onScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.onScroll)
},
methods: {
onScroll() {
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
let currentActive = null
headings.forEach(heading => {
const rect = heading.getBoundingClientRect()
if (rect.top < 100 && rect.bottom > 0) {
currentActive = heading.id
}
})
this.activeItem = currentActive
}
}
响应式目录设计
使用Vue的响应式特性实现目录的展开/折叠功能:
data() {
return {
expandedItems: {}
}
},
methods: {
toggleExpand(itemId) {
this.$set(this.expandedItems, itemId, !this.expandedItems[itemId])
}
}
与Vuex集成
对于大型应用,可以考虑将目录状态管理集成到Vuex中:
// store/modules/toc.js
export default {
state: {
items: [],
activeItem: null
},
mutations: {
SET_ITEMS(state, items) {
state.items = items
},
SET_ACTIVE_ITEM(state, itemId) {
state.activeItem = itemId
}
}
}
这些方法可以根据具体需求组合使用,构建出功能完善的目录系统。实际实现时应考虑性能优化,如对滚动事件进行节流处理,避免频繁的DOM操作等。







