u
This commit is contained in:
1 parent
e99a9fb274
commit
0be0b0767a
788 files changed
+112023
-14941
No files matched your search
@@ -0,0 +1,67 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* TOC 条目(递归)—— 照抄 Docus / @nuxt/ui ContentToc 的 ul>li>a 结构。
|
||||
*
|
||||
* 实测(docus.dev,1440px / light):
|
||||
* ul.list / ul.listWithChildren
|
||||
* a.link display:flex; align-items:center; padding:4px 0;
|
||||
* font-size:14px; line-height:20px; height:28px
|
||||
* border-radius:4px(rounded-sm)
|
||||
* color: text-muted
|
||||
* a.link:active color: text-primary;font-weight 仍为 400
|
||||
* h3 层级由父级 ul 的缩进体现(ms-3 = 12px)
|
||||
*/
|
||||
import { computed } from 'vue'
|
||||
|
||||
interface TocLink {
|
||||
id: string
|
||||
text: string
|
||||
children?: TocLink[]
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
link: TocLink
|
||||
level: number
|
||||
activeIds: string[]
|
||||
}>()
|
||||
|
||||
/** 点击时通知父级锁定该项为激活,避免滚动动画期间被 scrollspy 抢走 */
|
||||
const emit = defineEmits<{ navigate: [id: string] }>()
|
||||
|
||||
const isActive = computed(() => props.activeIds.includes(props.link.id))
|
||||
|
||||
const linkClass = computed(() => ['g3-toc-link', isActive.value ? 'is-active' : ''])
|
||||
|
||||
function onClick(e: MouseEvent) {
|
||||
const el = document.getElementById(props.link.id)
|
||||
if (!el) return
|
||||
e.preventDefault()
|
||||
// 先锁定,再滚动:这样无论落点是多少,点击的项一定是高亮的
|
||||
emit('navigate', props.link.id)
|
||||
el.focus({ preventScroll: true })
|
||||
// 滚到与 scrollspy 判据一致的位置:标题顶部对齐视口顶部下方一点,
|
||||
// 使「绝对位置 <= scrollY + 余量」在滚动结束后必然成立。
|
||||
el.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||
history.replaceState(null, '', `#${props.link.id}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li class="g3-toc-item">
|
||||
<a :class="linkClass" :href="`#${link.id}`" @click="onClick">
|
||||
<span class="g3-toc-link-text">{{ link.text }}</span>
|
||||
</a>
|
||||
|
||||
<ul v-if="link.children?.length" class="g3-toc-list-with-children">
|
||||
<G3TocItem
|
||||
v-for="child in link.children"
|
||||
:key="child.id"
|
||||
:link="child"
|
||||
:level="level + 1"
|
||||
:active-ids="activeIds"
|
||||
@navigate="emit('navigate', $event)"
|
||||
/>
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
Reference in new issue
Block a user