BasicLayout
是应用的根布局组件,负责:
BasicLayout
├── ConfigProvider (Ant Design 主题配置)
└── Layout
├── Row (品牌和状态区域 - 可配置位置)
│ ├── Col (品牌区域)
│ └── Col (状态区域)
├── Row (主内容区域)
│ ├── Col (导航区域 - 仅大屏显示)
│ └── Col (内容区域)
├── Row (品牌和状态区域 - 底部位置)
├── TabBar (移动端底部导航 - 仅小屏显示)
└── NavbarFloat (中等屏幕浮动导航)
屏幕尺寸 | 导航方式 | 品牌/状态栏 |
---|---|---|
xl (≥1200px) | 侧边 NavMenu | 显示 |
lg (≥992px) | 侧边 NavMenu | 显示 |
md (≥768px) | 浮动 NavbarFloat | 显示 |
sm (≥576px) | 底部 TabBar | 隐藏 |
xs (<576px) | 底部 TabBar | 隐藏 |
使用 contentMap
对象建立业务流程 key 与页面组件的映射关系:
const contentMap = {
exam: <ExamPage />,
process: <ImageProcessingPage />,
view: <ImageProcessingPage />,
register: <RegisterPage />,
worklist: <WorklistPage />,
// ... 其他页面
};
优势:
通过 Redux 的 currentKey
状态控制当前显示的页面:
const currentKey = useSelector(
(state: RootState) => state.BusinessFlow.currentKey
);
// 渲染对应页面
{
contentMap[currentKey];
}
从配置文件读取布局参数,支持动态调整:
{pageLayoutConfig.brandAndStatusPosition === 'top' && (
<Row>品牌和状态区域</Row>
)}
NavMenu
NavbarFloat
TabBar
通过 Tailwind CSS 的响应式工具类实现:
className = 'xl:hidden lg:hidden md:block';
使用父元素字体大小控制子元素(特别是图标)的尺寸:
className = 'xl:text-[48px] lg:text-[40px] md:text-[30px] ...';
子元素使用 text-[100%]
继承父元素字体大小,实现统一缩放。
children
:React.ReactNode(定义但未使用,保留用于扩展)currentKey
:当前业务流程标识(来自 BusinessFlowSlice
)pageLayoutConfig
:页面布局配置(品牌/状态栏位置)渲染输出:完整的应用布局结构,包含:
事件派发:
setBusinessFlow(key)
:更新业务流程状态通过 CSS 媒体查询和响应式工具类,使页面在不同屏幕尺寸下有不同表现。
实现方式:
将页面分为 24 列,通过 Col
组件的 span
值控制宽度。
示例:
<Col xl={4} lg={4} md={5} sm={0} xs={0}> // 大屏占4列,小屏隐藏
<Col xl={20} lg={20} md={19} sm={0} xs={0}> // 大屏占20列,小屏隐藏
使用对象字面量建立 key-value 映射,替代多个 if-else 或 switch 语句。
优势:
视图完全由状态决定,状态改变自动触发视图更新。
流程:
用户点击导航 → dispatch(setBusinessFlow) → currentKey 更新 → 组件重新渲染 → 显示新页面
根据条件决定是否渲染某个组件或元素。
方式:
{condition && <Component />}
{condition ? <A /> : <B />}
className="xl:block sm:hidden"
使用 CSS Flexbox 实现灵活的布局方式。
关键属性:
flex: 1
:占据剩余空间display: flex
:启用 flex 布局justify-end
:主轴末端对齐items-center
:交叉轴居中对齐将可变的参数提取到配置文件,提高代码的可维护性和灵活性。
示例:
// 配置文件
export const pageLayoutConfig = {
brandAndStatusPosition: 'top' // 或 'bottom'
};
// 使用配置
{pageLayoutConfig.brandAndStatusPosition === 'top' && <Row>...</Row>}
将大型组件拆分为多个小型、专注的组件,通过组合构建完整功能。
本文件中的组件组合:
NavMenu
:侧边导航菜单NavbarFloat
:浮动导航菜单StatusBar
:状态栏TabBar
:底部标签栏 const status: StatusBarProps = {
diskStatus: 'available',
batteryLevel: 0,
wifiStrength: 0,
heatCapacity: 0,
};
改进建议:应该从实际的状态或 Redux store 中获取
typescript
<TabBar.Item title="患者管理" ... />
改进建议:应该使用 i18n 系统
### 2. 未使用的 Props
children
prop 被定义但未使用,可能是为了未来扩展预留。
### 3. 重复代码
品牌和状态区域的代码重复了两次(top 和 bottom 位置),可以提取为独立组件。
### 4. TODO 项
代码中存在 TODO 注释,需要后续完善:
- MeButton 的登录状态和头像应该从实际状态获取
### 5. 响应式字体大小策略
通过顶层 Layout 设置字体大小,子元素使用 text-[100%]
继承,实现整体缩放。这是一个巧妙的设计,但需要确保所有子组件都支持这种方式。
## 相关文件
- src/layouts/NavMenu.tsx
:侧边导航菜单组件
- src/layouts/NavbarFloat.tsx
:浮动导航菜单组件
- src/layouts/StateBar.tsx
:状态栏组件
- src/states/BusinessFlowSlice.ts
:业务流程状态切片
- src/config/pageLayout.ts
:页面布局配置
- src/pages/*
:各个页面组件