add toc
This commit is contained in:
parent
0e84fd0760
commit
13ef2e3b36
@ -23,7 +23,9 @@
|
||||
"@pinia/nuxt": "^0.7.0",
|
||||
"github-markdown-css": "^5.8.1",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-anchor": "^9.2.0",
|
||||
"markdown-it-mathjax3": "^4.3.2",
|
||||
"markdown-it-toc-done-right": "^4.2.0",
|
||||
"mitt": "^3.0.1",
|
||||
"nuxt": "^3.14.159",
|
||||
"vue": "latest",
|
||||
|
@ -2,6 +2,7 @@
|
||||
const route = useRoute(),
|
||||
cid = route.params.cid as string,
|
||||
content = ref<IBlogResponse<IPostFull>>(),
|
||||
toc = ref<HTMLDivElement | null>(null),
|
||||
|
||||
getPost = get<IBlogResponse<IPostFull>, unknown>('/blog/index.php/api/post', {
|
||||
params: {
|
||||
@ -11,44 +12,81 @@ const route = useRoute(),
|
||||
}),
|
||||
|
||||
title = computed(() => content.value?.data.title || 'Can not see me... can not see me...'),
|
||||
text = computed(() => content.value?.data.text || '## Ops!'),
|
||||
text = computed(() => content.value ? content.value.data.text + '[[toc]]' : '## Ops!'),
|
||||
date = computed(() => new Date((content.value?.data.date.timeStamp || 0) * 1000)
|
||||
.toISOString()
|
||||
.split('T')[0],
|
||||
),
|
||||
category = computed(() => content.value?.data.category || 'default'),
|
||||
url = computed(() => content.value?.data.url || '/error/404')
|
||||
url = computed(() => content.value?.data.url || '/error/404'),
|
||||
bindAnchorClickEvent = () => {
|
||||
const autoGenTOC = document.querySelector('#toc')
|
||||
if (!autoGenTOC || !toc.value) return
|
||||
|
||||
toc.value.innerHTML = autoGenTOC.innerHTML
|
||||
autoGenTOC.remove()
|
||||
|
||||
toc.value.querySelectorAll('a').forEach((elem: HTMLElement) => {
|
||||
elem.onclick = (event: MouseEvent) => {
|
||||
event.preventDefault()
|
||||
|
||||
let id = elem.getAttribute('href') || ''
|
||||
if (id.startsWith('#'))
|
||||
id = id.replace('#', '')
|
||||
|
||||
const element = document.getElementById(id)
|
||||
if (element) {
|
||||
const offsetTop = element.offsetTop - 70
|
||||
window.scrollTo({ top: offsetTop, behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
content.value = await getPost()
|
||||
|
||||
onMounted(() => {
|
||||
bindAnchorClickEvent()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="container m-4 mx-auto rounded-xl bg-white p-8 shadow-md lg:max-w-screen-lg">
|
||||
<div class="mb-4 border-b-2 border-dashed border-gray-200 pb-4">
|
||||
<h1 class="text-center text-3xl font-bold">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<div class="flex w-full items-center justify-center gap-4 text-gray-600">
|
||||
<!-- 日期 -->
|
||||
<div class="flex items-center gap-2">
|
||||
<font-awesome-icon :icon="['far', 'clock']" />
|
||||
<time>{{ date }}</time>
|
||||
</div>
|
||||
<!-- 分类 -->
|
||||
<div class="flex items-center gap-2">
|
||||
<font-awesome-icon :icon="['far', 'folder']" />
|
||||
<span>{{ category }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<font-awesome-icon :icon="['fas', 'link']" />
|
||||
<a :href="url">原文链接</a>
|
||||
<div class="flex container m-4 mx-auto xl:max-w-screen-xl gap-4">
|
||||
<section class="container mx-auto rounded-xl bg-white p-8 shadow-md flex-shrink-0 lg:max-w-screen-lg">
|
||||
<div class="mb-4 border-b-2 border-dashed border-gray-200 pb-4">
|
||||
<h1 class="text-center text-3xl font-bold">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<div class="flex w-full items-center justify-center gap-4 text-gray-600">
|
||||
<!-- 日期 -->
|
||||
<div class="flex items-center gap-2">
|
||||
<font-awesome-icon :icon="['far', 'clock']" />
|
||||
<time>{{ date }}</time>
|
||||
</div>
|
||||
<!-- 分类 -->
|
||||
<div class="flex items-center gap-2">
|
||||
<font-awesome-icon :icon="['far', 'folder']" />
|
||||
<span>{{ category }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<font-awesome-icon :icon="['fas', 'link']" />
|
||||
<a :href="url">原文链接</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<markdown-section :content="text" />
|
||||
</section>
|
||||
<markdown-section :content="text" />
|
||||
</section>
|
||||
|
||||
<aside class="flex-1 overflow-hidden">
|
||||
<div class="rounded-xl p-8 bg-white shadow-md">
|
||||
<div ref="toc" />
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.toc-style {
|
||||
@apply truncate
|
||||
}
|
||||
</style>
|
||||
|
@ -2,10 +2,12 @@
|
||||
definePageMeta({
|
||||
maintenance: true,
|
||||
})
|
||||
|
||||
const s = '# markdown-it rulezz!\n\n[[toc]]\n## with markdown-it-toc-done-right rulezz even more!'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NuxtWelcome />
|
||||
<markdown-section :content="s" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -1,5 +1,7 @@
|
||||
import md, { type Options } from 'markdown-it'
|
||||
import mm from 'markdown-it-mathjax3'
|
||||
import anchor from 'markdown-it-anchor'
|
||||
import toc from 'markdown-it-toc-done-right'
|
||||
|
||||
const options: Options = {
|
||||
breaks: true,
|
||||
@ -15,6 +17,13 @@ export default defineNuxtPlugin(() => {
|
||||
const render = md(options)
|
||||
.use(mm, {
|
||||
})
|
||||
.use(anchor, {
|
||||
})
|
||||
.use(toc, {
|
||||
containerId: 'toc',
|
||||
itemClass: 'truncate',
|
||||
// format: (x: string, fn: (s: string) => string) => `<!--<span class="truncate">${fn(x)}</span>-->`,
|
||||
})
|
||||
return {
|
||||
provide: {
|
||||
mdRender: render,
|
||||
|
10
yarn.lock
10
yarn.lock
@ -4385,6 +4385,11 @@ magicast@^0.3.5:
|
||||
"@babel/types" "^7.25.4"
|
||||
source-map-js "^1.2.0"
|
||||
|
||||
markdown-it-anchor@^9.2.0:
|
||||
version "9.2.0"
|
||||
resolved "https://registry.npmmirror.com/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz#89375d9a2a79336403ab7c4fd36b1965cc45e5c8"
|
||||
integrity sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==
|
||||
|
||||
markdown-it-mathjax3@^4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.npmmirror.com/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz#1e34aa86f8560b283fd283008334adc2d6b05a37"
|
||||
@ -4393,6 +4398,11 @@ markdown-it-mathjax3@^4.3.2:
|
||||
juice "^8.0.0"
|
||||
mathjax-full "^3.2.0"
|
||||
|
||||
markdown-it-toc-done-right@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.npmmirror.com/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.2.0.tgz#3ccdce22d5022ffae7b991d07261b1b1de5459d0"
|
||||
integrity sha512-UB/IbzjWazwTlNAX0pvWNlJS8NKsOQ4syrXZQ/C72j+jirrsjVRT627lCaylrKJFBQWfRsPmIVQie8x38DEhAQ==
|
||||
|
||||
markdown-it@^14.1.0:
|
||||
version "14.1.0"
|
||||
resolved "https://registry.npmmirror.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45"
|
||||
|
Loading…
x
Reference in New Issue
Block a user