Refactor layout components for improved readability and consistency

This commit is contained in:
skytek_xinliang
2026-03-27 13:57:44 +08:00
parent 24f86c3fb5
commit 6e38211382
24 changed files with 235 additions and 190 deletions
+20 -20
View File
@@ -1,5 +1,5 @@
import { computed, onBeforeUnmount, onMounted, ref, watch, type Ref } from 'vue'
import type { AdminLayoutMenuItem } from '@/components/layouts/sk-admin-layout/types'
import { computed, onBeforeUnmount, onMounted, ref, type Ref, watch } from 'vue'
type ToggleSidebarPayload = {
drawer: boolean
@@ -14,12 +14,12 @@ type UseAdminLayoutStateOptions = {
emitUpdateIsRail: (value: boolean) => void
favoritesBarVisible: boolean | null
isMobile: Ref<boolean>
isRail: boolean | null
isRail: Ref<boolean | null> // 必須為 Ref,確保父層 prop 更新時 getter 能即時反映
menuItems: AdminLayoutMenuItem[]
onToggleSidebar: (payload: ToggleSidebarPayload) => void
}
export function useAdminLayoutState (options: UseAdminLayoutStateOptions) {
export function useAdminLayoutState(options: UseAdminLayoutStateOptions) {
const drawer = ref(true)
const mobileFavoritesPanel = ref(false)
const mobileMenuPath = ref<AdminLayoutMenuItem[]>([])
@@ -30,9 +30,9 @@ export function useAdminLayoutState (options: UseAdminLayoutStateOptions) {
const appBarHeight = ref(0)
const isRail = computed({
get: () => (options.isRail ?? localIsRail.value),
get: () => options.isRail.value ?? localIsRail.value,
set: (value: boolean) => {
if (options.isRail === null) {
if (options.isRail.value === null) {
localIsRail.value = value
return
}
@@ -42,7 +42,7 @@ export function useAdminLayoutState (options: UseAdminLayoutStateOptions) {
})
const showFavoritesBar = computed({
get: () => (options.favoritesBarVisible ?? localFavoritesBarVisible.value),
get: () => options.favoritesBarVisible ?? localFavoritesBarVisible.value,
set: (value: boolean) => {
if (options.favoritesBarVisible === null) {
localFavoritesBarVisible.value = value
@@ -54,7 +54,7 @@ export function useAdminLayoutState (options: UseAdminLayoutStateOptions) {
})
const showBreadcrumbBar = computed({
get: () => (options.breadcrumbBarVisible ?? localBreadcrumbBarVisible.value),
get: () => options.breadcrumbBarVisible ?? localBreadcrumbBarVisible.value,
set: (value: boolean) => {
if (options.breadcrumbBarVisible === null) {
localBreadcrumbBarVisible.value = value
@@ -77,16 +77,17 @@ export function useAdminLayoutState (options: UseAdminLayoutStateOptions) {
const mobileMenuLevels = computed(() =>
Array.from({ length: mobileCurrentLevel.value }, (_, index) => ({
level: index + 1,
title: index === 0 ? '主選單' : (mobileMenuPath.value[index - 1]?.title ?? `${index + 1}`),
title:
index === 0 ? '主選單' : (mobileMenuPath.value[index - 1]?.title ?? `${index + 1}`),
}))
)
function resetMobilePanels () {
function resetMobilePanels() {
mobileFavoritesPanel.value = false
mobileMenuPath.value = []
}
function toggleSidebar () {
function toggleSidebar() {
if (options.isMobile.value) {
drawer.value = !drawer.value
} else {
@@ -99,17 +100,17 @@ export function useAdminLayoutState (options: UseAdminLayoutStateOptions) {
})
}
function goToMobileLevel (level: number) {
function goToMobileLevel(level: number) {
mobileFavoritesPanel.value = false
mobileMenuPath.value = mobileMenuPath.value.slice(0, Math.max(0, level - 1))
}
function openMobileFavoritesPanel () {
function openMobileFavoritesPanel() {
mobileMenuPath.value = []
mobileFavoritesPanel.value = true
}
function handleMobileMenuClick (
function handleMobileMenuClick(
item: AdminLayoutMenuItem,
onSelect: (selectedItem: AdminLayoutMenuItem) => void
) {
@@ -121,7 +122,7 @@ export function useAdminLayoutState (options: UseAdminLayoutStateOptions) {
onSelect(item)
}
function handleSelectFavorite (
function handleSelectFavorite(
item: AdminLayoutMenuItem,
onSelect: (selectedItem: AdminLayoutMenuItem) => void
) {
@@ -129,25 +130,24 @@ export function useAdminLayoutState (options: UseAdminLayoutStateOptions) {
mobileFavoritesPanel.value = false
}
function toggleFavoritesBar (nextValue?: boolean) {
showFavoritesBar.value =
typeof nextValue === 'boolean' ? nextValue : !showFavoritesBar.value
function toggleFavoritesBar(nextValue?: boolean) {
showFavoritesBar.value = typeof nextValue === 'boolean' ? nextValue : !showFavoritesBar.value
}
function handleUnshrink () {
function handleUnshrink() {
isRail.value = false
}
let appBarObserver: ResizeObserver | null = null
function resolveObservedElement () {
function resolveObservedElement() {
const target = options.appBarRef.value as HTMLElement | { $el?: HTMLElement } | null
if (!target) return null
if (target instanceof HTMLElement) return target
return target.$el ?? null
}
function updateAppBarHeight () {
function updateAppBarHeight() {
const el = resolveObservedElement()
if (!el) return
appBarHeight.value = Math.round(el.getBoundingClientRect().height || 0)