perf: hoist expensive operations in useLayout

pull/4600/merge
Divyansh Singh 5 months ago
parent 2803b7e330
commit e5ab0676a9

@ -466,7 +466,7 @@ Returns layout-related data. The returned object has the following type:
interface {
isHome: ComputedRef<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebar: Readonly<ShallowRef<DefaultTheme.SidebarItem[]>>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
@ -474,7 +474,7 @@ interface {
hasAside: ComputedRef<boolean>
leftAside: ComputedRef<boolean>
headers: ShallowRef<DefaultTheme.OutlineItem[]>
headers: Readonly<ShallowRef<DefaultTheme.OutlineItem[]>>
hasLocalNav: ComputedRef<boolean>
}
```

@ -1,28 +1,23 @@
import { useMediaQuery } from '@vueuse/core'
import { onContentUpdated, useRoute } from 'vitepress'
import type { DefaultTheme } from 'vitepress/theme'
import { computed, shallowRef, watch } from 'vue'
import { inBrowser, onContentUpdated, useRoute } from 'vitepress'
import type { DefaultTheme, useLayout as expected } from 'vitepress/theme'
import { computed, shallowReadonly, shallowRef, watch } from 'vue'
import { getSidebar, getSidebarGroups } from '../support/sidebar'
import { useData } from './data'
import { getHeaders } from './outline'
import { useCloseSidebarOnEscape } from './sidebar'
const headers = shallowRef<DefaultTheme.OutlineItem[]>([])
const sidebar = shallowRef<DefaultTheme.SidebarItem[]>([])
export function useLayout() {
const { frontmatter, page, theme } = useData()
const is960 = useMediaQuery('(min-width: 960px)')
const is960 = shallowRef(false)
export function useLayout(): ReturnType<typeof expected> {
const { frontmatter, theme } = useData()
const isHome = computed(() => {
return !!(frontmatter.value.isHome ?? frontmatter.value.layout === 'home')
})
const sidebar = computed(() => {
const sidebarConfig = theme.value.sidebar
const relativePath = page.value.relativePath
return sidebarConfig ? getSidebar(sidebarConfig, relativePath) : []
})
const hasSidebar = computed(() => {
return (
frontmatter.value.sidebar !== false &&
@ -56,13 +51,13 @@ export function useLayout() {
return {
isHome,
sidebar,
sidebar: shallowReadonly(sidebar),
sidebarGroups,
hasSidebar,
isSidebarEnabled,
hasAside,
leftAside,
headers,
headers: shallowReadonly(headers),
hasLocalNav
}
}
@ -72,12 +67,36 @@ interface RegisterWatchersOptions {
}
export function registerWatchers({ closeSidebar }: RegisterWatchersOptions) {
const { frontmatter, theme } = useData()
const { frontmatter, page, theme } = useData()
watch(
() => [page.value.relativePath, theme.value.sidebar] as const,
([relativePath, sidebarConfig]) => {
const newSidebar = sidebarConfig
? getSidebar(sidebarConfig, relativePath)
: []
if (JSON.stringify(newSidebar) !== JSON.stringify(sidebar.value)) {
sidebar.value = newSidebar
}
},
{ immediate: true, deep: true, flush: 'sync' }
)
onContentUpdated(() => {
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
})
if (inBrowser) {
is960.value = window.innerWidth >= 960
window.addEventListener(
'resize',
() => {
is960.value = window.innerWidth >= 960
},
{ passive: true }
)
}
const route = useRoute()
watch(() => route.path, closeSidebar)

4
theme.d.ts vendored

@ -16,7 +16,7 @@ export default theme
export declare const useLayout: () => {
isHome: ComputedRef<boolean>
sidebar: ComputedRef<DefaultTheme.SidebarItem[]>
sidebar: Readonly<ShallowRef<DefaultTheme.SidebarItem[]>>
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
hasSidebar: ComputedRef<boolean>
isSidebarEnabled: ComputedRef<boolean>
@ -27,7 +27,7 @@ export declare const useLayout: () => {
/**
* The outline headers of the current page.
*/
headers: ShallowRef<DefaultTheme.OutlineItem[]>
headers: Readonly<ShallowRef<DefaultTheme.OutlineItem[]>>
/**
* Whether the current page has a local nav. Local nav is shown when the
* "outline" is present in the page. However, note that the actual

Loading…
Cancel
Save