Skyroc Web Kit
Admin Layouts

状态与页签

Admin Layouts 的运行时状态、菜单状态、页签状态、缓存和动态 badge 值更新

@skyroc/web-admin-layouts 使用 Jotai 和全局 store 管理布局运行时状态。业务页面可以读取这些状态,但更常见的是只通过布局组件自然消费。

状态分层

useAdminState
  管理布局运行时:移动端、侧边栏折叠、内容横向滚动、全屏内容、mix 菜单固定。

useMenus
  管理菜单原始数据:allMenus、quickReferenceMenus、home、initMenus、clearMenus。

useAdminMenus
  管理当前布局菜单视图:selectedKey、openKeys、一级/二级/子级菜单、当前路由菜单信息。

useAdminTab
  管理页签:homeTab、tabs、activeTabId、添加、关闭、清理、切换和缓存。

useAdminMenuBadges
  管理菜单 badge 动态值表。

useAdminState

useAdminState 面向布局运行时行为。

import { useAdminState } from '@skyroc/web-admin-layouts';

const CollapseButton = () => {
  const { siderCollapse, toggleSiderCollapse } = useAdminState();

  return (
    <button type="button" onClick={toggleSiderCollapse}>
      {siderCollapse ? 'Expand' : 'Collapse'}
    </button>
  );
};

常用返回值:

返回值说明
isMobile是否进入移动端布局。
siderCollapse侧边栏是否折叠。
toggleSiderCollapse切换侧边栏折叠。
fullContent是否隐藏 Header、Sider、Footer,只显示内容区。
contentXScrollable内容区是否启用横向滚动场景。
mixSiderFixedmix / hybrid 子菜单是否固定。

useMenus

useMenus 是菜单数据的源头,通常在认证初始化阶段调用。

const { initMenus } = useMenus();

async function initAuth() {
  const userInfo = await queryClient.ensureQueryData(queryUserInfoOptions());

  await initMenus(userInfo);

  return userInfo;
}

initMenus 会根据 routeMode 决定从静态 routeTree 生成菜单,或调用 loadDynamicRoutes 获取后端菜单。

useAdminMenus

useAdminMenus 面向菜单渲染和交互。

const {
  menus,
  firstLevelMenus,
  secondLevelMenus,
  childLevelMenus,
  selectedKey,
  openKeys,
  routerPushByKey
} = useAdminMenus();

常用返回值:

返回值说明
menus当前菜单分类下的完整 Ant Design 菜单树。
firstLevelMenus一级菜单,混合布局会使用。
secondLevelMenus当前一级菜单下的二级菜单。
childLevelMenus当前二级菜单下的子菜单。
selectedKey当前路由对应的选中菜单 key。
openKeys当前路由应该展开的父级 key。
currentMenu当前路由在 quickReferenceMenus 中的记录。
routerPushByKey根据菜单 key 跳转到对应路由。

useAdminTab

useAdminTab 管理路由页签。

const {
  activeTabId,
  allTabs,
  removeActiveTab,
  clearLeftTabs,
  clearRightTabs,
  clearOtherTabs
} = useAdminTab();

页签来源于 quickReferenceMenus。每次路由变化时,布局 effect 会把当前路由转换成 tab 并加入状态。

Tab 缓存

如果主题设置启用 tab 缓存,布局会把 tabs 写入 storage.globalTabs

useAdminTab()
  ├─ initTabStore()
  │    ├─ 读取 storage.globalTabs
  │    ├─ 过滤已经不存在的路由
  │    └─ 初始化 homeTab
  └─ cacheTabs()
       └─ 写入 storage.globalTabs

登录用户切换或退出时,应清理无效 tabs。apps/admin 的认证模块会在 clearAuth 中调用 cacheTabsclearMenus,保持菜单与页签状态一致。

动态菜单 Badge

菜单 badge 的配置在路由里,值可以在业务侧异步更新。

staticData: {
  menu: {
    badge: {
      type: 'normal',
      valueKey: 'message.unread'
    }
  }
}

组件内更新:

import { useAdminMenuBadges } from '@skyroc/web-admin-layouts';

const MessageBadgeSync = () => {
  const { setMenuBadgeValue } = useAdminMenuBadges();
  const unreadCount = useUnreadMessageCount();

  useEffect(() => {
    setMenuBadgeValue('message.unread', unreadCount);
  }, [setMenuBadgeValue, unreadCount]);

  return null;
};

非组件代码更新:

import { clearMenuBadgeValues, setMenuBadgeValue, setMenuBadgeValues } from '@skyroc/web-admin-layouts';

setMenuBadgeValue('message.unread', 8);

setMenuBadgeValues({
  'todo.count': 3,
  'audit.pending': 12
});

clearMenuBadgeValues(['message.unread']);

MenuBadge 会订阅同一个值表,所以数量更新不需要重新生成菜单树。

状态使用边界

  • 页面只需要更新菜单数量时,优先使用 useAdminMenuBadges
  • 页面需要跳转菜单时,使用 useAdminMenus().routerPushByKey
  • 业务按钮需要折叠侧边栏时,使用 useAdminState
  • tabs 的增删改查一般由布局内部处理,业务侧只在明确需要时调用 useAdminTab

On this page