实践范例¶
所谓实践范例,就是用 Microsoft.UI.Reactor(Reactor)原语做的一小段组合,用来解决某个 真实的 UI 问题 —— 登录、主从视图、设置、分页列表、模态确认、多步表单、 带建议的搜索、命令面板、拖拽重排。这里收录的并不是完整的应用; 每个范例都是一个展示该模式的单一界面,并且都附带一个可以克隆并改造的 小型文档应用。
图库¶
| 范例 | 展示的内容 |
|---|---|
| 登录 | 逐键校验、由 UseMutation 持有的提交状态、错误展示。 |
| 主从视图 | 由列表与记录驱动的双窗格布局。 |
| 设置页 | 为 Toggle / ComboBox / Slider 逐键使用 UsePersisted。 |
| 分页列表 | 带空/加载/错误状态与「加载更多」哨兵的 UseInfiniteResource。 |
| 模态对话框 | 带遮罩与条件渲染的确认模式。 |
| 多步表单 | 带逐步校验的向导式导航。 |
| 带建议的搜索 | 用 UseMemo 针对静态目录过滤出的建议列表。 |
| 命令面板 | 由键盘加速器打开、内含已过滤命令列表的叠加层。 |
| 拖拽重排 | 保持身份的键控列表重排,并提供键盘操作路径。 |
图库应用¶
class RecipesIndexApp : Component
{
public override Element Render() => VStack(12,
Heading("Recipes"),
TextBlock("Real-world compositions made of Reactor primitives.")
.Opacity(0.7),
VStack(8,
HStack(8,
Tile("Login", "Validation + async submit"),
Tile("Master-detail", "Selection-driven layout"),
Tile("Settings", "Persisted preferences")),
HStack(8,
Tile("Paginated list", "Loading + empty + error states"),
Tile("Modal dialog", "Scrim + confirmation flow"),
Tile("Multi-step form", "Wizard validation")),
HStack(8,
Tile("Search", "Memoized suggestions"),
Tile("Command palette", "Keyboard-opened overlay"),
Tile("Drag-reorder", "Keyed list reordering"))
)
).Padding(20);
private static Element Tile(string title, string sub) => VStack(4,
TextBlock(title).Bold(),
TextBlock(sub).Opacity(0.6)
).Padding(12);
}

这个图库所用的原语与每个范例页都相同 —— 用 VStack 做纵向布局、用 TextBlock 写说明文字、
用 HStack 排出每一行瓦片。那个瓦片辅助方法是私有的静态方法,而不是组件,
因此它没有 Hook 作用域:
private static Element Tile(string title, string sub) => VStack(4,
TextBlock(title).Bold(),
TextBlock(sub).Opacity(0.6)
).Padding(12);
本目录下的每一页都遵循同样的形态:
// 本目录下每个范例页都会从 docs/_pipeline/apps/recipe-<name>/ 引入一个小小的
// 专用文档应用。范例模板会渲染三个片段标记(state / shape / render),
// 外加一张供上方图库缩略图使用的截图。
class GalleryShape : Component
{
public override Element Render() => TextBlock("see docs/_pipeline/apps/recipe-*");
}
如何阅读一个实践范例¶
每个范例的形态都相同:
- 一段该范例的可运行代码片段,取自
docs/_pipeline/apps/recipe-<name>/下真实的 文档应用。 - 一张该范例运行时的截图,由文档流水线工具采集。
- 一两段走读说明,点出该范例组合了哪些原语,以及支撑这个模式的 设计决策。
这些范例倾向于组合既有工厂方法 —— 每个范例都不自定义
Component。若想把某个范例用到你的应用里,复制片段并把目录数据换成你自己的即可。
参考¶
| 原语 | 使用者 |
|---|---|
UseState |
大多数范例。 |
UsePersisted |
设置页。 |
UseMemo |
搜索。 |
UseMutation |
登录 —— 异步提交、进行中、错误。 |
UseInfiniteResource |
分页列表。 |
| 条件渲染 | 模态对话框、命令面板。 |
| 双窗格 HStack | 主从视图。 |
| 键控子项 | 拖拽重排。 |
提示¶
先找现成的范例,再动手写代码。 大多数「我需要一个设置页」或「我们需要一个登录表单」的需求, 都能由这些模式之一满足。范例就是那套组合;自己发明一套的代价, 就是调试它的代价。
范例是起点,不是成品。 把片段放进你的应用再改造它 —— 数据、样式令牌、校验 规则。这里真正有价值的是组合的形态。
在伸手找范例之前,先搜一遍控件目录。 由一个控件就能解决的问题(表单、 数据系统)不需要范例;范例是为那些横跨多个控件与 Hook 的 形态而存在的。