Skip to content

Commit f80d7e2

Browse files
committedJan 15, 2025·
fix(theme-default): fix setupHeaders, close #326
1 parent aab502f commit f80d7e2

File tree

4 files changed

+59
-49
lines changed

4 files changed

+59
-49
lines changed
 

‎themes/theme-default/src/client/components/VPPage.vue

-3
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@ import VPPageMeta from '@theme/VPPageMeta.vue'
33
import VPPageNav from '@theme/VPPageNav.vue'
44
import type { VNode } from 'vue'
55
import { Content } from 'vuepress/client'
6-
import { setupHeaders } from '../composables/index.js'
76
87
defineSlots<{
98
'top'?: (props: Record<never, never>) => VNode | VNode[] | null
109
'bottom'?: (props: Record<never, never>) => VNode | VNode[] | null
1110
'content-top'?: (props: Record<never, never>) => VNode | VNode[] | null
1211
'content-bottom'?: (props: Record<never, never>) => VNode | VNode[] | null
1312
}>()
14-
15-
setupHeaders()
1613
</script>
1714

1815
<template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { useThemeLocaleData } from '@theme/useThemeData'
2+
import type { MenuItem } from '@vuepress/helper/client'
3+
import { getHeaders } from '@vuepress/helper/client'
4+
import { watchImmediate } from '@vueuse/core'
5+
import type { InjectionKey, Ref } from 'vue'
6+
import { computed, inject, onMounted, provide, ref } from 'vue'
7+
import { usePageFrontmatter, useRoutePath } from 'vuepress/client'
8+
import type { DefaultThemeNormalPageFrontmatter } from '../../shared/index.js'
9+
10+
export type HeadersRef = Ref<MenuItem[]>
11+
12+
export const headersSymbol: InjectionKey<HeadersRef> = Symbol('headers')
13+
14+
/**
15+
* Inject headers
16+
*/
17+
export const useHeaders = (): HeadersRef => {
18+
const headers = inject(headersSymbol)
19+
20+
if (!headers) {
21+
throw new Error('useHeaders() is called without provider.')
22+
}
23+
return headers
24+
}
25+
26+
export const setupHeaders = (): void => {
27+
const headersRef: HeadersRef = ref([])
28+
29+
const routePath = useRoutePath()
30+
const themeLocale = useThemeLocaleData()
31+
const frontmatter = usePageFrontmatter<DefaultThemeNormalPageFrontmatter>()
32+
const levels = computed(
33+
() => frontmatter.value.sidebarDepth ?? themeLocale.value.sidebarDepth ?? 2,
34+
)
35+
36+
const updateHeaders = (): void => {
37+
if (levels.value <= 0) {
38+
headersRef.value = []
39+
return
40+
}
41+
42+
headersRef.value = getHeaders({
43+
levels: [2, levels.value + 1],
44+
ignore: ['.vp-badge'],
45+
})
46+
}
47+
48+
provide(headersSymbol, headersRef)
49+
50+
onMounted(() => {
51+
watchImmediate([levels, routePath], updateHeaders)
52+
})
53+
}

‎themes/theme-default/src/client/composables/useSidebarItems.ts

+4-46
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
import { resolveAutoLink } from '@theme/resolveAutoLink'
22
import { resolvePrefix } from '@theme/resolvePrefix'
3+
import { useHeaders } from '@theme/useHeaders'
34
import { useThemeLocaleData } from '@theme/useThemeData'
45
import type { MenuItem } from '@vuepress/helper/client'
5-
import {
6-
getHeaders,
7-
isLinkRelative,
8-
keys,
9-
startsWith,
10-
} from '@vuepress/helper/client'
11-
import type { ComputedRef, InjectionKey, Ref } from 'vue'
12-
import { computed, inject, onMounted, provide, ref, watch } from 'vue'
6+
import { isLinkRelative, keys, startsWith } from '@vuepress/helper/client'
7+
import type { ComputedRef, InjectionKey } from 'vue'
8+
import { computed, inject, provide } from 'vue'
139
import type { PageData } from 'vuepress/client'
1410
import {
1511
usePageData,
1612
usePageFrontmatter,
1713
useRoute,
1814
useRouteLocale,
19-
useRouter,
2015
} from 'vuepress/client'
2116
import { isPlainObject, isString } from 'vuepress/shared'
2217
import type {
@@ -29,43 +24,6 @@ import type {
2924
} from '../../shared/index.js'
3025
import type { SidebarHeaderItem, SidebarItem } from '../typings.js'
3126

32-
export type HeadersRef = Ref<MenuItem[]>
33-
34-
export const headersRef: HeadersRef = ref([])
35-
36-
export const setupHeaders = (): void => {
37-
const router = useRouter()
38-
const themeLocale = useThemeLocaleData()
39-
const frontmatter = usePageFrontmatter<DefaultThemeNormalPageFrontmatter>()
40-
const levels = computed(
41-
() => frontmatter.value.sidebarDepth ?? themeLocale.value.sidebarDepth ?? 2,
42-
)
43-
44-
router.beforeEach((to, from) => {
45-
if (to.path !== from.path) {
46-
headersRef.value = []
47-
}
48-
})
49-
50-
const updateHeaders = (): void => {
51-
if (levels.value <= 0) {
52-
headersRef.value = []
53-
return
54-
}
55-
56-
headersRef.value = getHeaders({
57-
levels: [2, levels.value + 1],
58-
ignore: ['.vp-badge'],
59-
})
60-
}
61-
62-
watch(levels, updateHeaders)
63-
64-
onMounted(updateHeaders)
65-
}
66-
67-
export const useHeaders = (): HeadersRef => headersRef
68-
6927
/**
7028
* Util to transform page header to sidebar item
7129
*/

‎themes/theme-default/src/client/config.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { setupDarkMode } from '@theme/useDarkMode'
2+
import { setupHeaders } from '@theme/useHeaders'
23
import { useScrollPromise } from '@theme/useScrollPromise'
34
import { setupSidebarItems } from '@theme/useSidebarItems'
45
import { hasGlobalComponent } from '@vuepress/helper/client'
@@ -25,6 +26,7 @@ export default defineClientConfig({
2526

2627
setup() {
2728
setupDarkMode()
29+
setupHeaders()
2830
setupSidebarItems()
2931
},
3032

0 commit comments

Comments
 (0)
Please sign in to comment.