3. Perspective 核心概念
学习 Ignition Perspective,最容易“卡住”的地方不是拖拽组件,而是没有把它的对象模型想清楚。Perspective 的 HMI/SCADA 画面并不是一张“画布”,而是一棵由视图、容器、组件构成的树;页面负责把这棵树挂到浏览器地址上;会话负责把用户与这棵树绑定;客户端类型则决定这棵树最终以什么形态呈现在设备上。理解这六个概念之间的关系,后续的绑定、参数、消息、页面导航、响应式布局都会顺理成章。
一、核心原理:从“画布思维”切换到“视图树思维”
在传统 Vision 中,窗口是基本单位,组件直接放在窗口上。Perspective 则不同:视图(View)是可复用的 UI 单元,它本身不直接对应浏览器地址;页面(Page)才是浏览器可访问的 URL 入口,一个页面会挂载一个根视图;容器(Container)是视图内部的布局节点,负责排列子组件;组件(Component)是叶子节点,如按钮、标签、表格、图表。它们的关系可以概括为:页面挂载根视图,视图内部由容器嵌套容器,最终容纳组件。
会话(Session)是用户打开 Perspective 客户端后,在 Gateway 上建立的一次有状态连接。它保存当前用户、项目、页面、视图实例、参数值、消息订阅等运行时信息。同一个项目可以被多个会话同时访问,每个会话拥有独立的视图实例和状态。客户端类型(Client Type)则决定会话以哪种形态呈现:桌面浏览器、移动设备、还是 Perspective 原生 App。客户端类型会影响可用组件、触摸交互、屏幕尺寸和性能策略。
一句话记忆:页面是地址,视图是模板,容器是布局,组件是内容,会话是运行实例,客户端类型是呈现形态。
二、方法流程:一次页面访问的完整链路
当用户在浏览器输入 /myproject/main 时,Perspective 内部大致经历以下步骤:
- Gateway 接收 HTTP 请求,解析项目名与页面路径。
- 根据页面配置找到对应的根视图路径,例如
Main/Overview。 - 为该用户创建或复用会话,加载项目资源与视图定义。
- 根据客户端类型(Desktop / Mobile / App)选择布局策略与组件渲染方式。
- 实例化视图树:根视图 → 容器 → 子容器 → 组件,并解析参数与绑定。
- 建立与 Gateway 的实时通道,订阅标签、消息、会话属性等数据源。
- 将渲染结果推送到浏览器,后续数据变化通过绑定自动刷新。
这个链路说明:视图是定义,会话是实例。同一个视图被两个用户打开,会产生两个独立的视图实例,参数和组件状态互不影响。这也是 Perspective 能支持多用户、多设备同时访问的基础。
三、结构图解:六者关系与数据流
下图用结构关系图展示页面、视图、容器、组件、会话与客户端类型之间的挂载与运行关系。左侧是设计期的静态结构,右侧是运行期的会话与客户端形态。
四、案例场景:多设备访问同一项目
假设一个水处理项目有一个 Main/Overview 视图,包含三个容器:顶部导航、左侧设备列表、右侧实时趋势。现在有三类用户同时访问:
- 中控室桌面浏览器:客户端类型为 Desktop,屏幕宽,三个容器横向展开,趋势图显示 8 条曲线。
- 巡检人员手机:客户端类型为 Mobile,布局自动切换为纵向堆叠,设备列表变为可折叠面板,趋势图只显示 2 条关键曲线。
- 车间平板 App:客户端类型为 App,使用触摸优化组件,按钮尺寸增大,支持离线缓存与推送。
这三个用户访问的是同一个页面、同一个视图定义,但各自拥有独立的会话。会话中保存了各自的登录用户、参数值(如当前选中的设备 ID)、消息订阅和视图实例状态。因此,巡检人员在手机上切换设备,不会影响中控室大屏的显示内容。这正是 Perspective 面向多用户、多终端 HMI 的核心优势。
五、常见误区与复盘
误区一:把视图当页面用。视图本身没有 URL,不能直接在浏览器打开。必须通过页面挂载,或通过页面导航、弹窗、嵌入等方式引用。设计时先规划页面结构,再规划视图复用。
误区二:认为会话就是登录用户。会话是连接实例,一个用户可以打开多个会话(多个标签页、多台设备),每个会话独立。会话属性(如 session.props.auth.user)才是用户相关信息的来源。
误区三:忽略客户端类型差异。同一个视图在 Desktop 和 Mobile 上可能表现完全不同。如果只用固定像素布局,移动端会出现横向滚动或组件重叠。应优先使用 Flex 容器和响应式断点。
复盘建议:在项目初期就画出一张“页面—视图—容器—组件”的树状清单,并标注每个页面对应的客户端类型。这样在后续做参数传递、消息订阅、页面导航时,能快速定位问题出在哪一层。
六、关键对象速查表
| 对象 | 作用 | 是否可复用 | 是否对应 URL | 典型属性/操作 |
|---|---|---|---|---|
| 页面 Page | 浏览器访问入口,挂载根视图 | 否,每个页面独立配置 | 是,如 /main |
页面路径、根视图、导航权限 |
| 视图 View | 可复用 UI 模板,承载容器与组件 | 是,可被多个页面引用 | 否 | 视图参数、输入/输出、消息处理 |
| 容器 Container | 布局节点,排列子组件与子容器 | 是,可嵌套 | 否 | Flex、坐标、断点、方向、间距 |
| 组件 Component | 叶子节点,提供具体交互与显示 | 是,可复制 | 否 | 属性、绑定、事件、样式 |
| 会话 Session | 运行期用户连接实例,保存状态 | 否,每个连接独立 | 否 | 用户、项目、页面、参数、订阅 |
| 客户端类型 Client Type | 决定呈现形态与交互方式 | 否,由访问方式决定 | 否 | Desktop、Mobile、App |
实践建议:在 Perspective 中做页面导航时,优先使用 system.perspective.navigate 或页面配置中的导航动作,而不是直接操作视图。视图负责“长什么样”,页面负责“在哪里”,会话负责“谁在用”,客户端类型负责“怎么用”。把这四件事分开思考,HMI 架构会清晰很多。
掌握这六个概念后,后续学习视图参数、消息处理、页面导航、会话属性、响应式布局时,就能明确每个功能作用在哪一层。Perspective 的灵活性正来自这种分层:定义与实例分离,结构与呈现分离,用户与设备分离。