Skip to content

useLayoutStore 布局状态

@fx/layouts 的 pinia store,承载 layout 业务状态(setting 设置系统 / tabs / maximized / refreshing / 首页),下沉自 web 原 appStorecollapsed / isDarksetting 派生(保持旧 API 兼容)。

引入

ts
import { useLayoutStore } from "@fx/layouts"

const layout = useLayoutStore()

状态

字段说明类型
collapsed侧边栏折叠boolean
tabs标签页列表TabItem[]
activeTab当前激活 pathstring
currentTab当前激活 path(computed 别名)string
maximized最大化boolean
isDark暗色模式boolean
refreshing刷新中boolean
homeTab首页 tab 定义(由 BasicLayout 解析后 setHome 注入)TabItem | null
homePath首页路径(homeTab?.path 派生,无首页时为 ""string
setting布局应用配置(见下节,单 key app_setting 持久化)AppSetting
settingFromStorage是否从持久化加载(BasicLayout prop 初值语义用)boolean
settingDrawerVisible设置抽屉显隐(瞬态,不持久化)boolean
activeTopMenuId一级菜单激活 id(双列/混合模式共享)number | null

方法

方法说明
toggleCollapse()切换侧边栏折叠
addTab(route)路由进入时添加标签
removeTab(path)关闭单个标签(固定标签不可关闭)
closeLeftTabs(path) / closeRightTabs(path) / closeOthers(path) / closeAll()批量关闭
sortTabs(oldIndex, newIndex)拖拽排序
toggleAffix(path)切换标签固定
restoreTabs(userId)登录后按 userId 恢复缓存
clearTabs()清空标签缓存(不同用户登录时调用)
toggleMaximize()切换最大化
toggleTheme()切换主题
triggerRefresh()触发刷新(只切 refreshing;清缓存由消费方监听 refreshed 处理)
setHome(tab)注入首页 tab(由 BasicLayout 解析后调用);确保首页 tab 存在且 affix、activeTab 落位;传 null 清除首页并移除旧首页 tab
updateSetting(patch)深合并更新 setting(见下节)
resetSetting()重置为 DEFAULT_APP_SETTING
openSettingDrawer() / closeSettingDrawer()设置抽屉显隐(瞬态)
setActiveTopMenu(id)同步一级菜单激活 id(BasicLayout 路由 watch 调用)

首页

store 不自行解析首页(初始化时 menus 未到),首页由 BasicLayout 解析后 setHome 注入。解析优先级(在 BasicLayout 完成):

  1. 菜单 is_home: true 节点
  2. BasicLayout homePath prop(消费方显式)
  3. 第一个可导航菜单项 / 静态路由项
  4. 无 → BasicLayout 渲染"暂无菜单权限"状态页
ts
// 通常由 BasicLayout 内部 watch 自动调用,消费方一般不直接用 setHome
layout.setHome({ name: "Dashboard", path: "/dashboard", title: "仪表盘" })

setting 设置系统

AppSetting 单对象、单 key app_setting 持久化(@fx/storagefuxi_<appName>_app_setting),由 FxSettingDrawer 编辑:

字段说明默认值
layoutMode布局模式(7 种,见 FxLayout"vertical"
collapsed侧栏折叠false
primaryColor主色(watch 写 --fx-color-primary;派生色阶不联动)"#1E293B"
isDark暗色模式(toggleTheme 切换)false
showHeader / showTabs / showBreadcrumb / showFooter显示开关true / true / true / false
watermark水印配置(嵌套对象),经 BasicLayout 透传 FxWatermark。字段见下表见下表
enableHotkeys全局快捷键开关(Ctrl+K 菜单搜索 / Ctrl+B 折叠侧栏 / Ctrl+, 打开设置)true
tabStyle标签风格(chrome / card / plain / brisk)"card"
contentWidth内容宽度(fluid / fixed 定宽居中)"fluid"
enablePageTransition页面切换动画总开关(关闭时无过渡,风格与速度失效)true
pageTransition页面切换动画风格("" 无 / fade 渐隐 / fade-up 上滑 / fade-down 下滑 / fade-left 左滑 / fade-right 右滑 / fade-scale 缩放;slide 为旧值仅兼容历史持久化,过渡类定义在包内全局样式)"fade"
pageTransitionDuration页面切换动画时长(秒,watch 写 --fx-page-transition-duration0.25
buttonPositionsetting 按钮位置(header / fixed 悬浮)"header"
headerMode顶栏模式(fixed / auto 滚动隐藏)"fixed"
sidebarWidth侧栏宽度(拖拽写回,clamp 180~320)220
sidebarDraggable侧栏可拖拽调宽true

watermark 字段(嵌套)

字段说明默认值
enabled开启水印false
blind暗水印(肉眼几乎不可见,需解码工具还原,透传 FxWatermark blindfalse
content水印内容(空串 = 回退应用标题)""
fontSize字号 px(透传 fontSize16
fontWeight字重(normal / bold,透传 fontWeight"normal"
color字体颜色(透传 fontColor"#000000"
opacity透明度 0-1(透传 globalAlpha0.15
rotate旋转角度 deg(透传 rotate-22
gap平铺间距 / 密度 px(透传 width / height,越大越稀疏)300

watermark 为嵌套对象,updateSetting 对其做深合并——补丁只需传变更字段,如 updateSetting({ watermark: { enabled: true } })

ts
layout.updateSetting({ layoutMode: "two-column" })
layout.updateSetting({ watermark: { enabled: true, blind: true } })
layout.resetSetting()

迁移:旧 app_theme key(存 "dark"/"light")在首次加载时并入 setting.isDark,旧 key 不再写入。

持久化

tabs / activeTab / setting 自动写入 @fx/storage,key 经 fuxi_<appName>_ 前缀拼接(appName 来自 VITE_APP_NAME),实现多应用隔离。

ts
// 登录后恢复该用户的标签页
layout.restoreTabs(user.id)

// 切换用户时清空
layout.clearTabs()

在 web 中使用

web 的 stores/app.tsuseLayoutStore 的别名 re-export,保持现有 useAppStore() 调用零改动:

ts
// web/src/stores/app.ts
export { useLayoutStore as useAppStore } from "@fx/layouts"