prevent multiple getHeaders calls

Co-authored-by: userquin <userquin@gmail.com>
pull/4673/head
Divyansh Singh 6 months ago
parent d37333a8a6
commit d827a6141b

@ -1,6 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { useRoute } from 'vitepress' import { computed, provide, useSlots } from 'vue'
import { computed, provide, useSlots, watch } from 'vue'
import VPBackdrop from './components/VPBackdrop.vue' import VPBackdrop from './components/VPBackdrop.vue'
import VPContent from './components/VPContent.vue' import VPContent from './components/VPContent.vue'
import VPFooter from './components/VPFooter.vue' import VPFooter from './components/VPFooter.vue'
@ -9,7 +8,8 @@ import VPNav from './components/VPNav.vue'
import VPSidebar from './components/VPSidebar.vue' import VPSidebar from './components/VPSidebar.vue'
import VPSkipLink from './components/VPSkipLink.vue' import VPSkipLink from './components/VPSkipLink.vue'
import { useData } from './composables/data' import { useData } from './composables/data'
import { useCloseSidebarOnEscape, useSidebarControl } from './composables/sidebar' import { registerWatchers } from './composables/layout'
import { useSidebarControl } from './composables/sidebar'
const { const {
isOpen: isSidebarOpen, isOpen: isSidebarOpen,
@ -17,10 +17,7 @@ const {
close: closeSidebar close: closeSidebar
} = useSidebarControl() } = useSidebarControl()
const route = useRoute() registerWatchers({ closeSidebar })
watch(() => route.path, closeSidebar)
useCloseSidebarOnEscape(isSidebarOpen, closeSidebar)
const { frontmatter } = useData() const { frontmatter } = useData()
@ -31,7 +28,11 @@ provide('hero-image-slot-exists', heroImageSlotExists)
</script> </script>
<template> <template>
<div v-if="frontmatter.layout !== false" class="Layout" :class="frontmatter.pageClass" > <div
v-if="frontmatter.layout !== false"
class="Layout"
:class="frontmatter.pageClass"
>
<slot name="layout-top" /> <slot name="layout-top" />
<VPSkipLink /> <VPSkipLink />
<VPBackdrop class="backdrop" :show="isSidebarOpen" @click="closeSidebar" /> <VPBackdrop class="backdrop" :show="isSidebarOpen" @click="closeSidebar" />

@ -1,10 +1,13 @@
import { useMediaQuery } from '@vueuse/core' import { useMediaQuery } from '@vueuse/core'
import { onContentUpdated } from 'vitepress' import { onContentUpdated, useRoute } from 'vitepress'
import { computed, shallowRef } from 'vue' import { computed, shallowRef, watch } from 'vue'
import type { MenuItem } from '../../shared' import { type MenuItem } from '../../shared'
import { getSidebar, getSidebarGroups } from '../support/sidebar' import { getSidebar, getSidebarGroups } from '../support/sidebar'
import { useData } from './data' import { useData } from './data'
import { getHeaders } from './outline' import { getHeaders } from './outline'
import { useCloseSidebarOnEscape } from './sidebar'
const headers = shallowRef<MenuItem[]>([])
export function useLayout() { export function useLayout() {
const { frontmatter, page, theme } = useData() const { frontmatter, page, theme } = useData()
@ -47,13 +50,6 @@ export function useLayout() {
: frontmatter.value.aside === 'left' : frontmatter.value.aside === 'left'
}) })
const headers = shallowRef<MenuItem[]>([])
// TODO: optimize this
onContentUpdated(() => {
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
})
const hasLocalNav = computed(() => { const hasLocalNav = computed(() => {
return headers.value.length > 0 return headers.value.length > 0
}) })
@ -70,3 +66,20 @@ export function useLayout() {
hasLocalNav hasLocalNav
} }
} }
interface RegisterWatchersOptions {
closeSidebar: () => void
}
export function registerWatchers({ closeSidebar }: RegisterWatchersOptions) {
const { frontmatter, theme } = useData()
onContentUpdated(() => {
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
})
const route = useRoute()
watch(() => route.path, closeSidebar)
useCloseSidebarOnEscape(closeSidebar)
}

@ -7,31 +7,19 @@ import {
watch, watch,
watchEffect, watchEffect,
watchPostEffect, watchPostEffect,
type ComputedRef, type ComputedRef
type Ref
} from 'vue' } from 'vue'
import { isActive } from '../../shared' import { isActive } from '../../shared'
import { hasActiveLink as containsActiveLink } from '../support/sidebar' import { hasActiveLink as containsActiveLink } from '../support/sidebar'
import { useData } from './data' import { useData } from './data'
export interface SidebarControl { const isOpen = ref(false)
collapsed: Ref<boolean>
collapsible: ComputedRef<boolean>
isLink: ComputedRef<boolean>
isActiveLink: Ref<boolean>
hasActiveLink: ComputedRef<boolean>
hasChildren: ComputedRef<boolean>
toggle(): void
}
/** /**
* a11y: cache the element that opened the Sidebar (the menu button) then * a11y: cache the element that opened the Sidebar (the menu button) then
* focus that button again when Menu is closed with Escape key. * focus that button again when Menu is closed with Escape key.
*/ */
export function useCloseSidebarOnEscape( export function useCloseSidebarOnEscape(close: () => void) {
isOpen: Ref<boolean>,
close: () => void
) {
let triggerElement: HTMLButtonElement | undefined let triggerElement: HTMLButtonElement | undefined
watchEffect(() => { watchEffect(() => {
@ -57,8 +45,6 @@ export function useCloseSidebarOnEscape(
} }
export function useSidebarControl() { export function useSidebarControl() {
const isOpen = ref(false)
function open() { function open() {
isOpen.value = true isOpen.value = true
} }
@ -81,7 +67,7 @@ export function useSidebarControl() {
export function useSidebarItemControl( export function useSidebarItemControl(
item: ComputedRef<DefaultTheme.SidebarItem> item: ComputedRef<DefaultTheme.SidebarItem>
): SidebarControl { ) {
const { page, hash } = useData() const { page, hash } = useData()
const collapsed = ref(false) const collapsed = ref(false)

Loading…
Cancel
Save