新增 文章目录功能

master
liuyx 2 years ago
parent ed456cf355
commit fec88430bd

@ -22,6 +22,7 @@ import Footer from '@/components/Footer.vue'
margin: 10px 0; margin: 10px 0;
.content { .content {
width: 65%; width: 65%;
// margin-top: 50px;
} }
} }
</style> </style>

@ -8,4 +8,5 @@
.el-card { .el-card {
border-radius: 10px; border-radius: 10px;
margin: 20px 0;
} }

@ -11,7 +11,9 @@
<!-- 文章标题和简述 --> <!-- 文章标题和简述 -->
<el-col :span="14"> <el-col :span="14">
<div class="blog-container"> <div class="blog-container">
<router-link :to="'/articles/' + item.id">
<h3>{{ item.title }}</h3> <h3>{{ item.title }}</h3>
</router-link>
<div class="description">{{ item.description }}</div> <div class="description">{{ item.description }}</div>
</div> </div>
</el-col> </el-col>

@ -48,6 +48,9 @@ watch(router.currentRoute, () => {
background-color: #fff; background-color: #fff;
padding: 0 30px; padding: 0 30px;
box-sizing: border-box; box-sizing: border-box;
// position: fixed;
// top: 0;
// z-index: 999;
} }
.right-header { .right-header {
display: flex; display: flex;

@ -22,7 +22,7 @@ const routes = [
component: () => import('@/views/about/About.vue') component: () => import('@/views/about/About.vue')
}, },
{ {
path: '/articles/:id', path: '/articles/:articleId',
component: () => import('@/views/article/Article.vue') component: () => import('@/views/article/Article.vue')
} }
] ]

@ -1,5 +1,5 @@
<template> <template>
<div>Archive</div> <el-card shadow="hover">Archives</el-card>
</template> </template>
<script setup></script> <script setup></script>

@ -1,12 +1,30 @@
<template> <template>
<el-row :gutter="20">
<el-col :span="18">
<el-card shadow="hover" class="article"> <el-card shadow="hover" class="article">
<v-md-preview :text="blog"></v-md-preview> <v-md-preview :text="blog" ref="preview"></v-md-preview>
</el-card> </el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover" class="directory">
<h3>目录</h3>
<div
v-for="anchor in directory"
:key="anchor"
:style="{ padding: `10px 0 10px ${anchor.indent * 20}px` }"
@click="handleAnchorClick(anchor)"
>
<a style="cursor: pointer">{{ anchor.title }}</a>
</div>
</el-card>
</el-col>
</el-row>
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from 'vue'
const blog = ` const blog = `
## 测试 ## 二级标题
这是一篇测试文章~ 这是一篇测试文章~
这是一篇测试文章~ 这是一篇测试文章~
@ -14,14 +32,71 @@ const blog = `
这是一篇测试文章~ 这是一篇测试文章~
这是一篇测试文章~ 这是一篇测试文章~
### 三级标题
1. a
2. b
3. c
#### 四级标题
~~~js ~~~js
console.log('这是一篇测试文章~') console.log('这是一篇测试文章~')
~~~ ~~~
## 实现目录功能
> v-md-editor可太好用了完美
::: tip
居然还有tip功能Amazing
:::
` `
const preview = ref()
const directory = ref([])
onMounted(() => {
console.log(preview.value.$el)
const anchors = preview.value.$el.querySelectorAll('h1,h2,h3,h4,h5,h6')
const titles = Array.from(anchors).filter((title) => !!title.innerText.trim())
if (!titles.length) {
directory.value = []
return
}
const hTags = Array.from(new Set(titles.map((title) => title.tagName))).sort()
directory.value = titles.map((el) => ({
title: el.innerText,
lineIndex: el.getAttribute('data-v-md-line'),
indent: hTags.indexOf(el.tagName)
}))
console.log(directory.value)
})
const handleAnchorClick = (anchor) => {
const { lineIndex } = anchor
const heading = preview.value.$el.querySelector(`[data-v-md-line="${lineIndex}"]`)
if (heading) {
preview.value.scrollToTarget({
target: heading,
scrollContainer: window,
top: 60
})
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.article { .article {
margin: 20px 0; margin: 20px 0;
} }
.directory {
position: sticky;
top: 10px;
}
</style> </style>

@ -1,5 +1,5 @@
<template> <template>
<div>Categories</div> <el-card shadow="hover">Categories</el-card>
</template> </template>
<script setup></script> <script setup></script>

@ -1,5 +1,5 @@
<template> <template>
<div>Tags</div> <el-card shadow="hover">Tags</el-card>
</template> </template>
<script setup></script> <script setup></script>

Loading…
Cancel
Save