1
- import { useMediaQuery } from '@vueuse/core'
2
- import { onContentUpdated , useRoute } from 'vitepress'
3
- import type { DefaultTheme } from 'vitepress/theme'
4
- import { computed , shallowRef , watch } from 'vue'
1
+ import { inBrowser , onContentUpdated , useRoute } from 'vitepress'
2
+ import type { DefaultTheme , useLayout as expected } from 'vitepress/theme'
3
+ import { computed , shallowReadonly , shallowRef , watch } from 'vue'
5
4
import { getSidebar , getSidebarGroups } from '../support/sidebar'
6
5
import { useData } from './data'
7
6
import { getHeaders } from './outline'
8
7
import { useCloseSidebarOnEscape } from './sidebar'
9
8
10
9
const headers = shallowRef < DefaultTheme . OutlineItem [ ] > ( [ ] )
10
+ const sidebar = shallowRef < DefaultTheme . SidebarItem [ ] > ( [ ] )
11
11
12
- export function useLayout ( ) {
13
- const { frontmatter, page, theme } = useData ( )
14
- const is960 = useMediaQuery ( '(min-width: 960px)' )
12
+ const is960 = shallowRef ( false )
13
+
14
+ export function useLayout ( ) : ReturnType < typeof expected > {
15
+ const { frontmatter, theme } = useData ( )
15
16
16
17
const isHome = computed ( ( ) => {
17
18
return ! ! ( frontmatter . value . isHome ?? frontmatter . value . layout === 'home' )
18
19
} )
19
20
20
- const sidebar = computed ( ( ) => {
21
- const sidebarConfig = theme . value . sidebar
22
- const relativePath = page . value . relativePath
23
- return sidebarConfig ? getSidebar ( sidebarConfig , relativePath ) : [ ]
24
- } )
25
-
26
21
const hasSidebar = computed ( ( ) => {
27
22
return (
28
23
frontmatter . value . sidebar !== false &&
@@ -56,13 +51,13 @@ export function useLayout() {
56
51
57
52
return {
58
53
isHome,
59
- sidebar,
54
+ sidebar : shallowReadonly ( sidebar ) ,
60
55
sidebarGroups,
61
56
hasSidebar,
62
57
isSidebarEnabled,
63
58
hasAside,
64
59
leftAside,
65
- headers,
60
+ headers : shallowReadonly ( headers ) ,
66
61
hasLocalNav
67
62
}
68
63
}
@@ -72,12 +67,36 @@ interface RegisterWatchersOptions {
72
67
}
73
68
74
69
export function registerWatchers ( { closeSidebar } : RegisterWatchersOptions ) {
75
- const { frontmatter, theme } = useData ( )
70
+ const { frontmatter, page, theme } = useData ( )
71
+
72
+ watch (
73
+ ( ) => [ page . value . relativePath , theme . value . sidebar ] as const ,
74
+ ( [ relativePath , sidebarConfig ] ) => {
75
+ const newSidebar = sidebarConfig
76
+ ? getSidebar ( sidebarConfig , relativePath )
77
+ : [ ]
78
+ if ( JSON . stringify ( newSidebar ) !== JSON . stringify ( sidebar . value ) ) {
79
+ sidebar . value = newSidebar
80
+ }
81
+ } ,
82
+ { immediate : true , deep : true , flush : 'sync' }
83
+ )
76
84
77
85
onContentUpdated ( ( ) => {
78
86
headers . value = getHeaders ( frontmatter . value . outline ?? theme . value . outline )
79
87
} )
80
88
89
+ if ( inBrowser ) {
90
+ is960 . value = window . innerWidth >= 960
91
+ window . addEventListener (
92
+ 'resize' ,
93
+ ( ) => {
94
+ is960 . value = window . innerWidth >= 960
95
+ } ,
96
+ { passive : true }
97
+ )
98
+ }
99
+
81
100
const route = useRoute ( )
82
101
watch ( ( ) => route . path , closeSidebar )
83
102
0 commit comments