理解 Zion 的 UI 组织方式
在 Zion 里构建 UI,不是从“拖哪些组件”开始,而是先判断:这个界面属于哪个客户端?它在哪个页面或弹窗里?由怎样的组件树构成?组件显示的数据来自哪个上下文?复杂界面应该用什么组合模式组织?
这篇文档建立这条线索:
先确定:界面属于哪个客户端
Zion 项目不是“一套 UI 到处发布”。一个项目由一个共享服务端和多个独立客户端组成。
| 端 | 承载内容 | 对应编辑器模块 |
|---|---|---|
| 服务端 | 数据库、API、行为流、权限、AI 能力等。一个项目只有一套服务端,各客户端共用。 | 设计 |
| 客户端 | 页面、弹窗、组件树、前端状态、端上交互与端专属配置。一个项目可以包含多个客户端。 | 数据、行为、设置 |
在编辑器顶部栏的 设计 模块中,客户端之间互不影响。相对地,在 数据、行为 或设置中修改服务端能力(如数据表、行为流、API、权限),会影响所有调用这些能力的客户端。
因此,构建 UI 的第一步是选择当前客户端。你在左边栏选择的是网页、微信小程序还是 App,决定了接下来看到的页面列表、画布、组件树和可用组件。
进入客户端后:页面是 UI 的边界
页面
页面是当前客户端下用于承载 UI 结构、数据绑定和前端行为的独立界面单元,通常对应一个可访问的路由或视图。
一个页面内部可以有组件树、页面级数据源、页面变量、页面入参和页面行为。
| 概念 | 说明 |
|---|---|
| 页面 | 当前客户端中的独立界面单元,通常对应路由或视图。 |
| 主页 | 当前客户端默认打开的页面。 |
| 页面数据源 | 页面级查询/订阅,供页面内部组件引用。 |
| 页面变量 | 页面内声明的临时变量,用于存储页面内的临时状态。 |
| 页面入参 | 页面跳转或链接传入的数据,用于初始化页面的上下文。 |
弹窗
弹窗也是独立的界面单元,但它不通过普通路由直接访问。弹窗通常由页面或组件上的行为打开,用来承载确认框、表单弹层、详情弹层、抽屉等悬浮视图。
| 概念 | 说明 |
|---|---|
| 弹窗 | 独立的悬浮视图,通常由页面或组件上的行为打开,用来承载确认框、表单弹层、详情弹层、抽屉等悬浮视图。 |
| 弹窗数据源 | 弹窗级查询/订阅,供弹窗内部组件引用。 |
| 弹窗变量 | 弹窗内声明的临时变量,用于存储弹窗内的临时状态。 |
| 弹窗入参 | 弹窗打开时传入的数据,用于初始化弹窗的上下文。 |
页面里面:组件树决定界面结构
组件是画布中的可配置界面单元,用于承载展示、输入、布局或交互能力。组件不是孤立存在的控件,而是组件树上的节点。
系统组件
系统组件,是Zion 提供的官方组件,分为基础组件和容器组件两类:
| 类型 | 说明 | 例子 |
|---|---|---|
| 基础组件 | 展示信息、采集输入或触发交互,无子组件。 | 文本、按钮、图片、输入框等 |
| 容器组件 | 承载子组件,决定子树的布局、滚动、上下文或显示条件。 | 页面、视图、列表项、标签页、条件分支等 |
自定义组件和代码组件
- 自定义组件,是将项目内搭好的组件结构保存为可复用组件。
- 代码组件,是利用 Zion 的开放能力,通过代码扩展的自定义组件。使用时,需提前导入。详情见 开发代码组件。
构建 UI 的重点不是堆叠控件,而是组织组件树:哪些节点负责展示,哪些节点负责布局,哪些节点提供上下文。
组件为什么能显示不同内容:上下文
同一个文本组件,为什么放在不同列表项里,能渲染出不同的商品名称?原因是组件属性可以绑定当前可见的上下文数据。
在 UI 搭建中,上下文可以从两个维度理解:
- 空间作用域:组件在当前位置能读取哪些数据。
- 时间作用域:一次行为执行前后,哪些数据可以作为输入或结果继续使用。
空间作用域:UI 渲染上下文
UI 渲染上下文决定组件在当前组件树位置上能读取哪些数据。页面级上下文提供页面范围内共享的数据;组件局部上下文则提供当前位置对应的数据。
| 作用域 | 上下文 | 来源 | 典型绑定场景 |
|---|---|---|---|
| 页面级 | 页面入参 | 页面打开时由跳转或链接传入 | 详情页 ID |
| 页面级 | 页面变量 | 页面运行期间保存的临时状态 | 当前筛选词、当前步骤、弹窗开关 |
| 页面级 | 页面数据源 | 页面级 数据查询/订阅 结果 | 多个区域共享同一份查询结果 |
| 组件局部 | 列表项 | 列表向列表项子画布提供的当前行数据 | 商品名称、价格、图片 |
| 组件局部 | 索引 | 列表向列表项子画布提供的当前行序号 | 排名、序号 |
| 特殊作用域 | 组件输出值 | 输入框、选择器等组件的输出 | 可被其他组件展示,或作为行为参数使用(不显示的条件容器不能对外提供输出) |
引用举例:在商品列表页面中,商品名称文本组件可以绑定当前列表项的商品名称字段,而排名文本组件可以绑定当前列表项的索引字段。
更完整的数据作用范围和数据绑定说明见 数据绑定。
时间作用域:行为运行时上下文
行为上下文描述一次交互发生时的数据流。它不是长期存在的页面状态,而是在行为执行过程中作为输入、输出或后续动作参数使用。
| 阶段 | 可用数据 | 用途 |
|---|---|---|
| 执行前 / 触发时 | 当前 UI 渲染上下文中的数据,例如当前列表项 ID、输入框输出值、页面变量 | 作为 API、数据库操作或行为流的输入参数 |
| 执行后 / 响应时 | API 返回值、行为流出参、数据库操作结果、上传结果等 | 赋值给页面变量、刷新数据源、显示提示、控制后续条件分支 |
引用举例:用户点击列表项中的「删除」按钮时,行为可以读取当前 列表项.id 作为删除参数。删除成功后,后续动作可以显示“删除成功”提示,并刷新列表数据源。
更完整的行为上下文机制见 行为交互模型。
复杂界面如何组织:选择组合模式
当界面变复杂时,不应只继续拖更多组件,而应该选择合适的组合方式。这里先建立选择直觉;完整配置项见 布局类组件参考。
| 组合模式 | 解决的问题 | 适合场景 | 关键上下文 / 子画布 |
|---|---|---|---|
| 视图 | 静态编组与布局 | 卡片、区块、局部滚动区域 | 子组件按视图布局排列 |
| 列表 | 同一套 UI 重复展示多条数据 | 商品列表、评论列表、消息列表 | 列表项、索引 |
| 条件容器 | 同一区域按条件显示不同 UI | 登录/未登录、角色差异、空状态/有数据状态 | 条件分支子画布 |
| 标签栏 | 同一页面内切换同级内容区 | 订单状态、商品分类、信息分组 | 标签页子画布 |
如何选择:
| 设计问题 | 优先考虑 |
|---|---|
| 想把几个组件组织成一块 | 视图 |
| 想用同一套结构展示多条数据 | 列表 |
| 想在同一区域按条件显示不同 UI | 条件容器 |
| 想在同一页面切换几个同级内容区 | 标签栏 |
回到多端:共享后端,不共享 UI
理解了客户端、页面、组件树和上下文后,再回到多端,就能避免一个常见误解:Zion 的多端不是把网页自动变成小程序或 App。
网页、微信小程序和 App 是彼此独立的客户端。网页 UI 不会同步到小程序,App 也不会继承小程序 UI。网页端的手机断点也不是微信小程序端,它只属于网页端响应式布局。
多端复用指的是复用服务端能力上,例如数据表、行为流、API、权限等。UI 层如果要复用局部结构,可以使用自定义组件或代码组件;跨客户端复用时,还需要考虑组件支持范围和端能力差异。
多端 UI 的核心意义是:后端能力共享,各客户端独立表达。
下一步看什么
如果你准备开始实际搭建页面,继续阅读 页面与组件基础操作。如果你想理解布局、定位、尺寸计算和网页端断点,阅读 布局系统。