UI/细节调整
This commit is contained in:
@@ -29,12 +29,13 @@ import { useModuleTabsStore, type ModuleTab } from '@/stores/moduleTabsStore'
|
||||
* ```
|
||||
*
|
||||
* ## 工作原理
|
||||
* 1. onMounted 时注册标签到 moduleTabsStore(**并复用该模块上次停留的 tab**),
|
||||
* TitleBar 据此渲染浮动切换器
|
||||
* 2. 用 IntersectionObserver 监听 TabsList 可见性(rootMargin 裁剪 TitleBar 高度)
|
||||
* 3. 双向 watch 同步本地 activeTab 与 store.activeTab
|
||||
* 4. 消费搜索导航的待跳转 tab(模块尚未挂载的场景)
|
||||
* 5. onUnmounted 时清理 observer 并把当前 tab 记到 store(按模块)后注销标签
|
||||
* 1. **setup 阶段(首帧之前)** 定下要显示的 tab:搜索跳转 > 上次停留 > 声明时的初始值
|
||||
* —— 模块切回来是重新挂载,等到 onMounted 再改就会先渲染一帧初始页(闪一下)
|
||||
* 2. onMounted 时注册标签到 moduleTabsStore,TitleBar 据此渲染浮动切换器
|
||||
* 3. 用 IntersectionObserver 监听 TabsList 可见性(rootMargin 裁剪 TitleBar 高度)
|
||||
* 4. 双向 watch 同步本地 activeTab 与 store.activeTab
|
||||
* 5. 消费搜索导航的待跳转 tab(模块尚未挂载的场景)
|
||||
* 6. onUnmounted 时清理 observer 并把当前 tab 记到 store(按模块)后注销标签
|
||||
*
|
||||
* ## 约束
|
||||
* - TitleBar 高度固定为 40px (h-10),composable 内部已用 44px 裁剪(含缓冲)
|
||||
@@ -45,11 +46,32 @@ import { useModuleTabsStore, type ModuleTab } from '@/stores/moduleTabsStore'
|
||||
export function useModuleTabs(
|
||||
moduleId: string,
|
||||
activeTab: Ref<string>,
|
||||
tabs: ModuleTab[]
|
||||
tabs: ModuleTab[],
|
||||
/** alwaysVisible: 模块自身不渲染 TabsList,标题栏切换器常驻(内容最大化模式) */
|
||||
options: { alwaysVisible?: boolean } = {}
|
||||
): Ref<HTMLElement | null> {
|
||||
const tabsStore = useModuleTabsStore()
|
||||
const tabsListRef = ref<HTMLElement | null>(null)
|
||||
|
||||
/**
|
||||
* 首次渲染前就定下要显示的 tab:搜索跳转 > 上次停留 > 声明时的初始值。
|
||||
*
|
||||
* 必须在 setup 里做。模块切走时组件被卸载、`activeTab` 随之丢失,切回来重新挂载
|
||||
* 时它是声明时的初始值(如 proxy 的 `'overview'`);若等到 onMounted 才恢复,
|
||||
* 首帧已经按初始值渲染过一次 —— 表现为「先闪一下第一页,再跳到上次停留页」,
|
||||
* 而不是一次干净的进入动画。
|
||||
*
|
||||
* 这里只**读** store(rememberedTab / peekPendingTab 都不改状态):注册仍留在
|
||||
* onMounted,避免从未挂载的组件污染 store 的当前模块。
|
||||
*/
|
||||
const pendingTab = tabsStore.peekPendingTab(moduleId)
|
||||
if (pendingTab && tabs.some(t => t.value === pendingTab)) {
|
||||
activeTab.value = pendingTab
|
||||
} else {
|
||||
const restored = tabsStore.rememberedTab(moduleId, tabs, activeTab.value)
|
||||
if (restored !== activeTab.value) activeTab.value = restored
|
||||
}
|
||||
|
||||
let observer: IntersectionObserver | null = null
|
||||
|
||||
/** 应用待跳转 tab(若属于当前模块的 tab 列表) */
|
||||
@@ -103,7 +125,12 @@ export function useModuleTabs(
|
||||
const restored = tabsStore.registerTabs(moduleId, tabs, activeTab.value)
|
||||
if (restored !== activeTab.value) activeTab.value = restored
|
||||
await nextTick()
|
||||
setupObserver()
|
||||
// 常驻模式:模块不渲染 TabsList,直接让标题栏切换器显示
|
||||
if (options.alwaysVisible) {
|
||||
tabsStore.setFloatingVisible(true)
|
||||
} else {
|
||||
setupObserver()
|
||||
}
|
||||
// 搜索导航跳转:模块刚挂载,消费待跳转 tab(优先级高于上次停留)
|
||||
applyPendingTab()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user