vue实现书籍目录
实现书籍目录的基本思路
使用Vue实现书籍目录需要结合组件化开发思想,通过数据驱动视图的方式动态渲染目录结构。核心在于构建树形数据结构,并通过递归组件或循环嵌套实现多级目录展示。
数据准备
典型的目录数据结构可采用嵌套数组形式,每个节点包含标题、章节编号和可能的子节点:
const menuData = [
{
title: "第一章 基础篇",
id: "chap1",
children: [
{ title: "1.1 安装指南", id: "chap1-1" },
{ title: "1.2 快速入门", id: "chap1-2" }
]
},
{
title: "第二章 进阶篇",
id: "chap2",
children: [
{
title: "2.1 核心概念",
id: "chap2-1",
children: [
{ title: "2.1.1 响应式原理", id: "chap2-1-1" }
]
}
]
}
]
递归组件实现
创建可递归调用的目录组件:
<template>
<ul class="menu-list">
<li v-for="item in data" :key="item.id">
<div @click="handleClick(item)" class="menu-item">
{{ item.title }}
</div>
<menu-tree
v-if="item.children"
:data="item.children"
@select="(val) => $emit('select', val)"
/>
</li>
</ul>
</template>
<script>
export default {
name: 'MenuTree',
props: {
data: {
type: Array,
required: true
}
},
methods: {
handleClick(item) {
this.$emit('select', item)
}
}
}
</script>
<style scoped>
.menu-list {
list-style: none;
padding-left: 1em;
}
.menu-item {
cursor: pointer;
padding: 4px 0;
}
.menu-item:hover {
color: #42b983;
}
</style>
父组件集成
在主页面中使用目录组件并处理点击事件:

<template>
<div class="book-container">
<div class="sidebar">
<menu-tree
:data="menuData"
@select="handleSelect"
/>
</div>
<div class="content">
<h2>{{ currentTitle }}</h2>
<!-- 内容区域 -->
</div>
</div>
</template>
<script>
import MenuTree from './MenuTree.vue'
export default {
components: { MenuTree },
data() {
return {
menuData: [...], // 填入之前的数据
currentTitle: ''
}
},
methods: {
handleSelect(item) {
this.currentTitle = item.title
// 这里可以添加跳转逻辑或内容加载逻辑
}
}
}
</script>
<style>
.book-container {
display: flex;
}
.sidebar {
width: 250px;
border-right: 1px solid #eee;
}
.content {
flex: 1;
padding: 0 20px;
}
</style>
动态加载优化
对于大型书籍目录,可采用异步加载方式优化性能:
async loadChapter(id) {
const res = await fetch(`/api/chapters/${id}`)
const data = await res.json()
this.$set(this.menuData[index], 'children', data.children)
}
交互增强
添加展开/折叠功能:

<div @click="toggleExpand(item)" class="menu-item">
{{ item.title }}
<span v-if="item.children">
{{ item.expanded ? '−' : '+' }}
</span>
</div>
在数据模型中添加expanded属性,通过v-show控制子菜单显示:
methods: {
toggleExpand(item) {
this.$set(item, 'expanded', !item.expanded)
}
}
样式美化
使用CSS增强视觉效果:
.menu-item {
transition: all 0.3s;
position: relative;
padding-left: 20px;
}
.menu-item:before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 10px;
height: 1px;
background: currentColor;
}
.menu-item:hover {
background: rgba(66, 185, 131, 0.1);
}
路由集成
与vue-router结合实现页面跳转:
handleSelect(item) {
this.$router.push({
path: '/book',
query: { chapter: item.id }
})
}






