refactor(app): extract page logic into composable drivers
This commit is contained in:
+69
-9
@@ -1,17 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { mdiHome } from '@mdi/js'
|
||||
import MainLayout from '@/components/layouts/MainLayout.vue'
|
||||
import PlainLayout from '@/components/layouts/PlainLayout.vue'
|
||||
import { useAppShell } from '@/composables/layout/useAppShell'
|
||||
import AppTabs from './AppTabs.vue'
|
||||
import GlobalOverlays from './GlobalOverlays.vue'
|
||||
import type { LayoutMenuItem } from '@/stores/menu'
|
||||
|
||||
defineProps<{
|
||||
menuItems?: LayoutMenuItem[]
|
||||
}>()
|
||||
type AppTabsInstance = InstanceType<typeof AppTabs>
|
||||
type GlobalOverlaysInstance = InstanceType<typeof GlobalOverlays>
|
||||
|
||||
const route = useRoute()
|
||||
const appTabs = ref<AppTabsInstance | null>(null)
|
||||
const globalOverlays = ref<GlobalOverlaysInstance | null>(null)
|
||||
|
||||
const layoutMap = {
|
||||
default: MainLayout,
|
||||
@@ -22,14 +24,72 @@ const activeLayout = computed(
|
||||
() => layoutMap[route.meta.layout as 'default' | 'none'] || MainLayout
|
||||
)
|
||||
const showTabs = computed(() => route.meta.layout === 'default')
|
||||
|
||||
function clearTabs() {
|
||||
appTabs.value?.clearTabs()
|
||||
}
|
||||
|
||||
const {
|
||||
favoriteActionIcon,
|
||||
favoriteActionLabel,
|
||||
favoritesStore,
|
||||
goHome,
|
||||
handleLayoutAction,
|
||||
handleLogout,
|
||||
handleRemoveFavorite,
|
||||
handleSelect,
|
||||
isFavoriteActionDisabled,
|
||||
layoutProps,
|
||||
menuStore,
|
||||
mergedMenuItems,
|
||||
toggleFavorite,
|
||||
} = useAppShell({ onLogout: clearTabs })
|
||||
|
||||
function handleSearch(value: string) {
|
||||
globalOverlays.value?.handleSearch(value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component :is="activeLayout">
|
||||
<AppTabs :menu-items="menuItems" :show-tabs="showTabs">
|
||||
<slot />
|
||||
<component
|
||||
:is="activeLayout"
|
||||
v-bind="layoutProps"
|
||||
v-model:breadcrumb-bar-visible="favoritesStore.breadcrumbBarVisible"
|
||||
v-model:favorites-bar-visible="favoritesStore.favoritesBarVisible"
|
||||
v-model:is-rail="menuStore.isRail"
|
||||
@action="handleLayoutAction"
|
||||
@logout="handleLogout"
|
||||
@remove-favorite="handleRemoveFavorite"
|
||||
@search="handleSearch"
|
||||
@select="handleSelect"
|
||||
>
|
||||
<template #breadcrumb-actions>
|
||||
<v-btn
|
||||
color="secondary"
|
||||
:disabled="isFavoriteActionDisabled"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
@click="toggleFavorite"
|
||||
>
|
||||
<v-icon class="mr-1" size="14" :icon="favoriteActionIcon" />
|
||||
{{ favoriteActionLabel }}
|
||||
</v-btn>
|
||||
<v-btn class="ml-2" color="primary" size="small" variant="text" @click="goHome">
|
||||
<v-icon class="mr-1" size="14" :icon="mdiHome" />
|
||||
返回首頁
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<AppTabs ref="appTabs" :menu-items="mergedMenuItems" :show-tabs="showTabs">
|
||||
<router-view v-if="showTabs" v-slot="{ Component }">
|
||||
<keep-alive>
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
|
||||
<router-view v-else />
|
||||
</AppTabs>
|
||||
</component>
|
||||
|
||||
<GlobalOverlays :menu-items="menuItems" @search-select="$emit('searchSelect', $event)" />
|
||||
<GlobalOverlays ref="globalOverlays" :menu-items="mergedMenuItems" @search-select="handleSelect" />
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user