From 6ce97965a15f33e342bb69d835c814a7b2f044c3 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Mon, 25 Mar 2024 01:06:44 +0800 Subject: [PATCH] =?UTF-8?q?perf(theme):=20=E4=BC=98=E5=8C=96sidebar=20?= =?UTF-8?q?=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- theme/src/client/components/SidebarItem.vue | 6 ++++ theme/src/client/composables/hash.ts | 12 ++++++++ theme/src/client/composables/sidebar.ts | 31 ++++++++++++++++----- 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 theme/src/client/composables/hash.ts diff --git a/theme/src/client/components/SidebarItem.vue b/theme/src/client/components/SidebarItem.vue index eb1ebb58..9218cbf3 100644 --- a/theme/src/client/components/SidebarItem.vue +++ b/theme/src/client/components/SidebarItem.vue @@ -171,6 +171,12 @@ function onCaretClick() { color: var(--vp-c-text-2); } +.sidebar-item.level-0.has-active > .item > .text, +.sidebar-item.level-1.has-active > .item > .text, +.sidebar-item.level-2.has-active > .item > .text, +.sidebar-item.level-3.has-active > .item > .text, +.sidebar-item.level-4.has-active > .item > .text, +.sidebar-item.level-5.has-active > .item > .text, .sidebar-item.level-0.has-active > .item > .link > .text, .sidebar-item.level-1.has-active > .item > .link > .text, .sidebar-item.level-2.has-active > .item > .link > .text, diff --git a/theme/src/client/composables/hash.ts b/theme/src/client/composables/hash.ts new file mode 100644 index 00000000..a263e899 --- /dev/null +++ b/theme/src/client/composables/hash.ts @@ -0,0 +1,12 @@ +import { ref } from 'vue' +import { inBrowser } from '../utils/index.js' + +const hashRef = ref(inBrowser ? location.hash : '') + +if (inBrowser) { + window.addEventListener('hashchange', () => { + hashRef.value = location.hash + }) +} + +export { hashRef } diff --git a/theme/src/client/composables/sidebar.ts b/theme/src/client/composables/sidebar.ts index 93953e4c..7d5f18f8 100644 --- a/theme/src/client/composables/sidebar.ts +++ b/theme/src/client/composables/sidebar.ts @@ -7,13 +7,16 @@ import type { import { useNotesData } from '@vuepress-plume/plugin-notes-data/client' import { useMediaQuery } from '@vueuse/core' import type { ComputedRef, Ref } from 'vue' -import { computed, onMounted, onUnmounted, ref, watchEffect } from 'vue' +import { computed, onMounted, onUnmounted, ref, watch, watchEffect } from 'vue' import type { PlumeThemePageData } from '../../shared/index.js' import { isActive } from '../utils/index.js' import { useThemeLocaleData } from './themeData.js' +import { hashRef } from './hash.js' + +export { useNotesData } export function normalizePath(path: string) { - return path.replace(/\/\\+/g, '/').replace(/\\+/g, '/') + return path.replace(/\/\\+/g, '/').replace(/\/+/g, '/') } export function getSidebarList(path: string, notesData: NotesData) { @@ -23,6 +26,16 @@ export function getSidebarList(path: string, notesData: NotesData) { return link ? notesData[link] : [] } +export function getSidebarFirstLink(sidebar: NotesSidebarItem[]) { + for (const item of sidebar) { + if (item.link) + return item.link + if (item.items) + return getSidebarFirstLink(item.items as NotesSidebarItem[]) + } + return '' +} + export function useSidebar() { const route = useRoute() const notesData = useNotesData() @@ -112,19 +125,23 @@ export function useCloseSidebarOnEscape( export function useSidebarControl(item: ComputedRef) { const page = usePageData() - const collapsed = ref(false) + const collapsed = ref(item.value.collapsed ?? false) const collapsible = computed(() => { - return item.value.collapsed != null + return item.value.collapsed !== null && item.value.collapsed !== undefined }) const isLink = computed(() => { return !!item.value.link }) - const isActiveLink = computed(() => { - return isActive(page.value.path, item.value.link) - }) + const isActiveLink = ref(false) + const updateIsActiveLink = () => { + isActiveLink.value = isActive(page.value.path, item.value.link) + } + + watch([page, item, hashRef], updateIsActiveLink) + onMounted(updateIsActiveLink) const hasActiveLink = computed(() => { if (isActiveLink.value)