中篇・运笔|统一 DataModel 底座,HT UI 组件万物同源

By | 2026年8月31日

上一篇讲了 HT UI 选用 Canvas 绘制界面的缘由。

这一篇换个视角,聊聊框架的组件储备与底层统一架构:内置组件品类是否充足,组件繁多后如何保持规整,规整之外界面能否完整导出复用。

评判一套绘图工具的功底,不在于能绘制多少元素,而在于万千组件共享同一套底层逻辑。

01 先报个菜单,治一治选择困难

技术选型的第一道难关,往往不是库好不好用,而是组件覆盖是否齐全。

兴冲冲选定一套组件库,开发中途才发现缺少日期选择器、树表格、属性面板,于是开始满世界找第三方组件拼凑、反复踩坑,甚至修改源码 —— 做过项目的人都深有体会。

多方拼凑出的界面会造成交互、视觉标准不统一,页面整体割裂杂乱。

下面摊开 HT UI 组件清单,罗列数十种组件,覆盖绝大多数业务场景:

  • 基础控件
    按钮、开关、复选框、单选框、文本输入框、文本域、下拉选择器、取色器、日期时间选择器、滑块、进度条、评分组件……
  • 数据展示
    普通表格、树形表格、纯树形组件、列表、属性面板、网格、时间轴、轮播、标签、步骤条……
  • 容器与导航
    普通面板、弹窗、抽屉、多标签页、侧边栏、右键菜单、气泡浮窗……
  • 布局家族
    边框布局、横向 / 纵向布局、网格布局、相对布局、流式布局、多列布局、可拖拽分割面板……
  • 高阶组件
    内置 Monaco 代码编辑器、文件上传组件、调色面板、消息通知、移动端适配选择器……

下图为基于 HT UI 搭建的可视化 UI 编辑器:按钮、树形控件、数据表格、属性面板、各类布局容器协同运行,全部由框架自有组件构成。

可以重点留意独立划分的布局组件体系,这也是 HT UI 极易被忽略的核心优势。

市面上大部分前端组件库依赖 CSS 完成页面排版,开发者需要手写大量 flex、grid 样式代码。

HT UI 把布局器做成了“独立一等公民”,边框、横纵、网格、相对、流式、分割……每一种布局都拥有完整生命周期,测量、排版、绘制逻辑分层清晰,各司其职。

如果需要开发定制化布局容器,仅需继承基类、重写两个函数,自定义逻辑与业务组件完全复用同一套开发思路。

组件品类已经足够齐全,但品类繁多也会带来新问题:各类组件是各自独立、逻辑割裂,还是共用同一套底层逻辑?这就要讲到 HT UI 真正的内核:DataModel

02 万物皆 Data:一套模型统全局

整篇系列最核心的观点,希望你能记住:

在 HT 的体系中,界面上所有可见、不可见元素,底层本质都是一份 Data 数据对象。

树形组件的一条节点是 ht.Data,表格的一行数据是 ht.Data,拓扑图上一台机房设备、一条连线,同样是 ht.Data。而统一管理所有 Data 的容器,便是 DataModel(业内常简称为 dm)。

这意味着掌握一套数据操作 API,就能适配几乎全部组件。

向树形组件新增节点、向表格新增行、向列表新增条目,操作逻辑高度统一:

// 以树表格组件举例
var tablePane = new ht.ui.TreeTablePane(),
    tableView = tablePane.getTableView(),
    dataModel = tableView.dm();          // 获取全局统一数据模型

// 创建数据实例,无需区分组件类型,统一为 ht.Data
var node = new ht.Data();
node.setName('机房 A');
node.a('status', 'online');              // a() 简写存储自定义业务属性,无字段限制
node.a('temperature', 26.5);

dataModel.add(node);                      // 写入数据模型,绑定组件自动刷新界面

注意看 node.a(‘status’, ‘online’):a() 是 attr 属性的简写,支持随意挂载自定义业务属性,无预设字段约束。

今日存储设备在线状态,明日挂载经纬度,后天记录温湿度,数据模型均可兼容,渲染层按需读取使用即可,无需提前定义字段、修改数据结构。

03 同源联动:一源多显,自动同步

DataModel 最吸引人的特性,是组件间数据联动几乎零开发成本。

同一个 DataModel 实例,可同时绑定多个不同组件:


var dm = new ht.DataModel();

// 左侧树形组件、右侧表格组件,共用同一套数据源
var treeView  = new ht.ui.TreeView();
var tableView = new ht.ui.TableView();
treeView.setDataModel(dm);
tableView.setDataModel(dm);

接下来神奇的事发生了:

在左侧树上选中“机房 A”,右侧表格对应行自动同步高亮;从 dm 中删除一条数据,两个组件同步移除对应内容。全程无需手动编写同步代码,只因所有组件读取的是同一份原始数据。

背后是一套朴素却高效的设计理念:界面不存储数据,仅作为数据的可视化镜像。

数据发生变更,视图自动更新;想要修改界面内容,直接操作底层数据即可,无需操作 DOM 或组件实例。

做过多组件联动开发的开发者,一定踩过“修改一处组件,忘记同步其他视图,数据展示不一致”的坑,(看到这句是不是会有点想哭。)但图扑这套机制能从根源规避这类问题。

行业常说 “约定优于配置”,这里也得自嘲一句:

做可视化开发很容易陷入一个误区 —— 为不同组件设计差异化数据格式。树有树的脾气,表有表的规矩,多组件联动需要堆砌大量胶水代码,改一处崩三处。

DataModel 的作用,就是统一全组件数据规范。学会一套 API,所有组件通用。

04 属性页:一次教科书级的示范

如果前面的概念还是略显抽象,那看 PropertyView 属性面板你将会瞬间通透。

这类交互场景十分常见:左侧选中对象,右侧面板自动列出所有可编辑得属性 —— 名字使用文本框、颜色使用拾色器、开关使用开关按钮、数值使用滑块。IDE、可视化设计工具、组态软件、游戏编辑器中随处可见(前文截图右侧面板便是该组件)。

在其他前端框架中,实现该功能需要编写大量绑定逻辑:监听控件变更同步对象、监听对象变更回填控件,双向绑定代码繁琐,来回拉扯极易出现遗漏。

而 HT UI 中,待编辑对象本身就是 ht.Data,属性面板仅需配置属性与编辑器的对应关系:


var propertyView = new ht.ui.PropertyView();
propertyView.setProperties([
    { name: 'name',  displayName: '名称', editable: true, editorClass: 'ht.ui.editor.StringEditor' },    
    { name: 'status', displayName: '状态', accessType: 'attr',
      valueType: 'boolean', editable: true },                                // 自动用开关
    { name: 'color',  displayName: '颜色', accessType: 'attr',
      valueType: 'color', editable: true, editorClass: 'ht.ui.editor.ColorEditor' }                              
]);
propertyView.dm().add(node);   // 把上面那个 ht.Data 丢进来
propertyView.dm().sm().ss(node); // 选中 data 进行显示和编辑

修改面板控件,底层 Data 自动更新;其他业务逻辑修改 Data,面板同步回显最新值 —— 双向绑定、零开发成本,无需手写任何同步逻辑。这便是统一数据模型带来的长期收益:底层规范统一一次,上层所有“数据↔介面”双向交互,自然无缝打通。组件场景越丰富,这份优势越突出。

05 界面也能”打包带走”:序列化

聊完组件丰富度与数据统一性,再介绍一项低调但关键时刻刚需的能力:序列化

HT UI 支持将整套界面存储成一段 JSON 字符串,后续可通过反序列化一键还原全部界面。

仅一行 API 即可实现,衍生出大量实用场景:

  • 可视化编辑器存档
    用户在组态工具拖拽搭建界面后,将 JSON 存入数据库;再次打开页面执行反序列化,完整还原布局、数据、滚动位置等全部状态。
  • 配置驱动界面
    界面布局不再硬编码至代码,而是由 JSON 配置文件控制。修改 JSON 即可调整界面结构,甚至由运营、后台动态下发不同布局配置区分客户,无需前端迭代发版。
  • 跨端、多人协作
    界面转化为可传输的纯数据,任意环境均可还原相同布局,无需口头描述调整细节。

序列化功能实现顺畅,根源依旧是统一数据模型:所有界面元素均标准化为 Data 对象,转为 JSON 只是基础能力延伸。

底层架构的统一,在这里再次体现价值。这也是前文反复强调 DataModel 的原因:它并非单一独立功能,而是串联组件拓展、多组件联动、界面存档的核心主线。

06 这一篇,请记住三句话

  • 组件品类齐全。
    数十类基础、高阶组件搭配完整布局器,常规业务无需拼凑第三方组件。
  • 万物皆 Data。
    依托统一 DataModel 管理全组件数据,一套操作逻辑适配所有组件,多视图联动几乎零成本。
  • 界面可完整序列化导出。
    一键转为 JSON 存档、动态配置页面、跨端协作都能轻松实现。

组件储备充足、数据流转顺畅、界面支持存档复用,但一套成熟的工具组件库,还需要适配各类使用场景:日间亮色模式、夜间暗色模式、多语言国际化、移动端自适应,全部要兼顾。

下一篇,聊聊组件多样适配能力

且看同一支画笔,如何适配各类场景风格。