news 2026/10/7 2:20:38

Golden Layout 2.0 迁移指南:TypeScript 重构下的 API 变更、Config 体系与兼容策略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Golden Layout 2.0 迁移指南:TypeScript 重构下的 API 变更、Config 体系与兼容策略
  • 前端
  • UI组件

【免费下载链接】golden-layout

A multi window layout manager for webapps

项目地址:https://gitcode.com/gh_mirrors/go/golden-layout
点击查看免费下载

Golden Layout(本仓库即 golden-layout,一个面向 Web 应用的多窗口布局管理器)在 2.0 版本中从 JavaScript 整体移植到了 TypeScript,并以此为契机对内部结构进行了大规模重构。本文以官方 Version 2 迁移说明 为骨架,结合仓库源码(config.ts、golden-layout.ts、layout-manager.ts 等)逐项梳理 v1(1.5.9)到 v2 的破坏性变更、弃用项与替代 API,帮助已有应用开发者完成平滑迁移,也帮助新使用者从一开始就采用正确的 v2 写法。

从 1.5.9 到 2.0:一次以可靠性为核心的 TypeScript 重写

v2 相对 v1(1.5.9)是一次实质性的大版本变更,官方总结为两点:

  1. 代码移植到 TypeScript:整个代码库以 TypeScript 重写,并同步完成了大范围的代码清理;
  2. 维护重心转向可靠性:v2 的维护工作将优先保证库本身的稳定与健壮。

由于这次重构力度很大,官方明确提示:在从 v1 迁移之前,务必先通读本节及以下各节的变更说明,尤其是"被移除的特性"与"弃用 API"两部分,避免在不知情的情况下依赖已失效的能力。

被移除的特性(Dropped Features)

作为移植的一部分,代码库被显著重构,一批在 v1 中"实现不够健壮、无法达到 v2 可靠性要求"的特性被正式移除:

被移除的特性说明与替代方案
React 支持官方不再在 Golden Layout 内提供 React 组件支持,并建议 React 开发者改用专为 React 组件设计的 FlexLayout 库
嵌套 Stack(Nested Stacks)v1 虽可拼出嵌套 Stack 布局,但实现并不完整;由于修复成本过高,官方决定直接移除该能力。v2 明确不允许嵌套 Stack
内部/公开 API 混用所有类、接口、函数与属性都被标记为internal或public两种之一,应用只能使用public元素(详见下文"Public and Internal APIs")
旧浏览器支持库现在只面向现代浏览器,目标浏览器列表(browserslist)配置在 package.json 中:最近 1 个版本的 Chrome / Firefox、最近 2 个版本的 Edge / Safari / iOS Safari,以及 Firefox ESR
jQuery 依赖Golden Layout 内部不再使用 jQuery(很多人把这视为新增特性而非损失)

迁移到 v2 的总体原则

v2 用 TypeScript 重写并伴随整体代码清理。API 方面,官方尽量保留了向后兼容:凡是为兼容而保留的函数与属性都被标记为@deprecated,并强烈建议应用迁移到新 API。需要注意,弃用项相关的缺陷会被赋予低优先级(甚至不修复),且弃用的别名、方法与属性可能在后续版本中被移除。

Config 与 Resolved Config:双层配置体系

v2 最核心的架构变化是配置系统被拆成两层,并且全部强类型化:

  1. Config(配置):应用开发者日常打交道的类型。支持可选属性,未指定的属性会使用默认值;同时负责向后兼容,会把已弃用的旧属性自动迁移到新属性上。Golden Layout API 方法中的配置参数类型均为Config(接口即LayoutConfig)。唯一的例外是LayoutManager.saveLayout(),它返回的是 Resolved Config;
  2. Resolved Config(已解析配置):Golden Layout 内部统一使用 Resolved Config。每当 API 函数收到一个 Config,库内部会调用LayoutConfig.resolve()将其解析为 Resolved Config——该过程为所有未指定的可选属性填充默认值,并处理向后兼容,从而保证库始终在"全量配置"下工作。从源码看,ResolvedLayoutConfig带有resolved: true标记字段,LayoutConfig.isResolved()正是据此区分两类对象(见 resolved-config.ts 与 config.ts)。

配置持久化的正确姿势

  • 保存:总是保存LayoutManager.saveLayout()返回的Resolved Config;
  • 加载:先通过LayoutConfig.fromResolved()把保存的 Resolved Config 转回 Config,再交给loadLayout()。

ResolvedLayoutConfig还直接提供了两个配置压缩/解压函数:

  • minifyConfig()—— 递归地把配置的键与值替换为单字母代号,替代旧LayoutManager.minifyConfig();
  • unminifyConfig()—— 把压缩后的配置还原,替代旧LayoutManager.unminifyConfig()。

这两者内部都经由ConfigMinifier.translateObject()实现(见 resolved-config.ts),并且弹窗窗口的配置传输(localStorage 中转)也依赖该机制(见 virtual-layout.ts)。

接口层级:ItemConfig 与 LayoutConfig

Resolved Config 与 Config 各自拥有两套接口层级:

  • ItemConfig:描述一个内容项(content item)的配置;
  • LayoutConfig(v1 中名为Config的接口):描述整个布局的配置。

其中RowOrColumnItemConfig、StackItemConfig、ComponentItemConfig等均继承自ItemConfig;RootItemConfig表示可以作为布局根的内容项类型(row、column、stack、component四选一,见 config.ts)。

ItemConfig.id:类型收窄为string

ItemConfig.id的可选属性类型从 v1 的string | string[]收窄为string。为向后兼容,解析(resolve)时仍接受字符串数组类型的id,以兼容旧的已保存配置。解析规则(见HeaderedItemConfig.resolveIdAndMaximised(),config.ts):

  1. 若id是数组,先检查其中是否包含旧版最大化标记__glMaximised,若存在则提取该标记作为maximised状态;
  2. 数组的第一个元素成为id的字符串值;
  3. 其余元素被丢弃。

componentType取代componentName

ComponentItemConfig.componentName已被ComponentItemConfig.componentType取代。componentType的类型为JsonValue(即可被 JSON 序列化的任意值,可以是字符串、数字、布尔等),但如果该组件类型要通过以下任一函数注册,componentType必须为string类型:

  1. GoldenLayout.registerComponent()(已弃用);
  2. GoldenLayout.registerComponentConstructor();
  3. GoldenLayout.registerComponentFactoryFunction()。

从源码看,解析时若componentType未定义会回退读取旧的componentName(见 config.ts);而getComponentInstantiator()通过ResolvedComponentItemConfig.resolveComponentTypeName()把componentType解析为注册表可用的字符串名称,非字符串的componentType将无法命中注册表(见 golden-layout.ts)。componentType是字符串时还会被用作组件标题的默认值(ComponentItemConfig.componentTypeToTitle())。

LayoutConfig.root:必填属性

LayoutConfig的root属性指定布局根内容项的ItemConfig,它不是可选的,必须始终指定(类型为RootItemConfig | undefined,其中undefined表示空布局,见 config.ts)。源码中的LayoutConfig.resolve()也保留了 v1 的兼容路径:若root未指定而旧content数组存在,则取content[0]作为根(见 config.ts)。

selectionEnabled移除,改用stackHeaderClick

LayoutConfig的selectionEnabled属性已被移除。点击 Stack 标题栏的选中行为改为通过新的stackHeaderClick事件处理,且该事件始终启用。

更多被弃用的 Config 属性

许多 Config 属性因为与其他属性重叠或迁移到了更合适的位置而被标记弃用,官方建议直接查阅源码注释了解详情:见 config.ts 中的@deprecated标注(如width/height→size,minWidth/minHeight→minSize,hasHeaders/showPopoutIcon/showCloseIcon/showMaximiseIcon→header下的show/popout/close/maximise等)。其中值得注意的新尺寸语法:

  • ItemConfig.size:格式为<数字><单位>,目前仅支持fr与%;对 row 表示高度、对 column 表示宽度。分配算法为:先按%比例分配空间,若不足 100% 则由fr按比例补足;若超过 100%,则给fr项额外分配 50% 后再统一回缩到 100%;
  • ItemConfig.minSize:格式为<数字><单位>,目前仅支持px。

配置解析(parseSize())会对非数字部分、未知单位、不支持的单位分别抛出ConfigurationError(见 config.ts)。

创建LayoutConfig的完整可运行示例,可直接参考仓库中的 apitest 演示程序。

类层次:GoldenLayout → VirtualLayout → LayoutManager

v2 中GoldenLayout成为独立类,继承关系为:

LayoutManager(抽象基类) └── VirtualLayout └── GoldenLayout

应用应总是创建GoldenLayout或VirtualLayout的实例,而不是直接实例化LayoutManager。

GoldenLayout/VirtualLayout构造函数接收 3 个可选参数:

  1. HTML 元素:承载 Golden Layout 实例的 DOM 元素;不指定时默认挂在body下(setContainer()会把body的 height/margin/padding 重置为 0、overflow 设为 clip,见 layout-manager.ts);
  2. bindComponentEvent事件处理器:用于以事件方式绑定组件(v2 新增绑定方式);
  3. unbindComponentEvent事件处理器。

重要变更:初始布局不再传入构造函数,而是在构造后通过LayoutManager.loadLayout()加载。旧式的new GoldenLayout(config)构造签名仍在,但已被标记@deprecated(见 golden-layout.ts 的兼容重载)。

组件注册 API 的调整

v2 把组件注册职责收拢到GoldenLayout类中,LayoutManager不再包含任何组件注册函数。注册函数的具体变化:

  1. registerComponentConstructor()(新函数):行为与旧registerComponent()相同,但仅用于注册组件构造函数;
  2. registerComponentFactoryFunction()(新函数):行为与旧LayoutManager.registerComponent()相同,但仅用于注册创建组件的回调函数(闭包);
  3. 不要使用registerComponent(),改用上述两个新函数之一。registerComponent()目前仍会按"是否有prototype属性"自动分派到构造函数或工厂函数注册,但已被标记弃用(见 golden-layout.ts)。

另外还有registerComponentFunction()(已弃用)与registerGetComponentConstructorCallback(),后者注册一个"按配置返回组件构造函数"的回调,仅在组件类型未注册时兜底调用(见 golden-layout.ts)。

LayoutManager 的方法迁移清单

LayoutManager是EventEmitter的抽象子类,v2 对其公开方法做了系统性调整,核心对照如下:

v1 用法v2 用法说明
new GoldenLayout(config, container)new GoldenLayout(container)+loadLayout(config)构造后通过loadLayout()加载布局;loadLayout()可随时再次调用以整体替换当前布局(见 layout-manager.ts)
手动调用init()不要手动调用只要不在构造函数传入旧式 LayoutConfig,init()会被内部自动调用
toConfig()saveLayout()saveLayout()返回当前布局的Resolved Config(见 layout-manager.ts)
minifyConfig()/unminifyConfig()ResolvedLayoutConfig.minifyConfig()/unminifyConfig()迁移到 Resolved Config 上
updateSize()setSize(width, height)以像素设置 Golden Layout 实例尺寸(见 layout-manager.ts)
root(属性)rootItem(新属性)rootItem是布局的根内容项(Ground 内容项的唯一子级);root已被内部属性groundItem取代,且groundItem仅限内部使用

组件焦点(Focus)相关新 API

  • focusComponent(item, suppressEvent?):聚焦指定组件项。任意时刻只有一个组件项持有焦点;若此前有其他组件项聚焦,它会自动失焦(blur)。焦点变化时会触发对应的focus/blur事件,除非suppressEvent参数为true;
  • clearComponentFocus(suppressEvent?):移除现有组件项焦点;若焦点被移除会触发blur事件,除非suppressEvent为true。

底层由LayoutManager.setFocusedComponentItem()实现:切换焦点时会先对旧焦点项调用setBlurred(),再对新项调用setFocused(),并同步更新父级(ComponentParentableItem)的聚焦态(见 layout-manager.ts)。

VirtualLayout 与组件绑定

VirtualLayout实现了除组件注册函数以外的全部 Golden Layout 功能;若应用只打算通过bindComponentEvent使用虚拟组件,可直接创建VirtualLayout实例而非GoldenLayout。

相关事件变更:

  • getComponentEvent:仍在VirtualLayout中实现,但已弃用,改用VirtualLayout.bindComponentEvent;
  • releaseComponentEvent:已弃用,改用VirtualLayout.unbindComponentEvent。

关于 v2 引入的四种组件绑定方式(Embedding via Registration / Embedding via Events / Virtual via Registration / Virtual via Events)的完整说明、事件签名与代码示例,见 绑定组件(Binding Components)文档。

Content Items:命名与行为变化

v2 对内容项体系做了大量重命名与语义调整:

v1 名称v2 名称说明
AbstractContentItemContentItem内容项基类
ItemContainerComponentContainer组件容器
ComponentComponentItem布局内的组件项;"Component" 一词现在专指被 Golden Layout 承载的外部组件
RootGroundItem已标记为 internal,应用永远不应访问 GroundItem;布局的根 ContentItem 是 GroundItem 的唯一子级,可通过LayoutManager.rootItem访问
Stack.getActiveContentItem()/setActiveContentItem()Stack.getActiveComponentItem()/setActiveComponentItem()语义不变,仅更名

其余行为调整:

  • config属性已移除:改用toConfig()方法(这也是原版 Golden Layout 文档一直推荐的写法);此前config中的部分属性(如id、type)现在作为ContentItem或其子类的属性直接可用;
  • id类型为string(不再支持string | string[]);
  • ContentItem.select()/deselect()已移除:改用新的ComponentItem.focus()与ComponentItem.blur();
  • ComponentItem.focus()(新函数):聚焦指定组件项,同时移除先前其他组件项的焦点,任意时刻只有一个组件项有焦点;若布局焦点发生变化会触发focus事件(除非suppressEvent为true);
  • ComponentItem.blur()(新函数):移除指定组件项的焦点,调用后布局内将没有任何组件项持有焦点;若组件失去焦点会触发blur事件(除非suppressEvent为true)。

一个值得注意的实现细节:createContentItem()会自动为"不在 Stack 内的 Component 配置"包一层 Stack(除非它是弹窗窗口的顶层项),因此即使配置中直接写了component根项,最终也会以 Stack 容纳(见 layout-manager.ts)。

ComponentContainer 的新能力

ComponentContainer(旧ItemContainer)在 v2 中新增了多项能力:

  • element(新属性,替代getElement()):返回承载组件的 HTMLElement;getElement()已弃用;
  • initialState(新 getter):获取创建该组件所用ComponentItemConfig的componentState;
  • stateRequestEvent(新事件):一旦设置,每当 Golden Layout 需要组件的最新状态时就会触发该事件。调用LayoutManager.saveLayout()会触发它(若已定义);若未定义,则保存 ItemConfig 中的初始状态或最近一次setState()设置的状态;
  • beforeComponentRelease(新 EventEmitter 事件):组件被释放前在容器上触发,组件可借此释放资源;
  • setState()已标记弃用:如已迁移到新的stateRequestEvent,应优先使用该事件;只有仍在使用弃用的setState()时才继续用getState();
  • replaceComponent():可在不影响布局其他部分的情况下替换容器内的组件(内部会先释放旧组件、用新 ItemConfig 重新绑定,见 component-container.ts)。

此外,虚拟组件绑定还依赖容器的virtualRectingRequiredEvent、virtualVisibilityChangeRequiredEvent、virtualZIndexChangeRequiredEvent等事件与virtual属性(用于区分虚拟/嵌入绑定方式),详见 component-container.ts 与 绑定组件文档。

Header 与 Tab:属性与函数重命名

header.ts 与 tab.ts 中有多个属性与函数被重命名,官方建议直接在这两个文件中搜索@deprecated标注来获取完整的改名对照清单。

事件系统升级

v2 的事件系统整体升级:

  1. 所有 DOM 事件现在都会向上传播,从而可被父级或全局处理;
  2. 任何事件监听器都不再调用preventDefault();
  3. 冒泡事件现在携带EventEmitter.BubblingEvent参数(或其子类)发出。

新增的 EventEmitter 事件:

事件类型触发时机
beforeComponentRelease—组件被释放前
stackHeaderClickBubbling点击 Stack 标题栏(但非 Tab)时
stackHeaderTouchStartBubbling触摸 Stack 标题栏(但非 Tab)时
focusBubbling组件获得焦点时
blurBubbling组件失去焦点时

其它行为变化:undefined取代null

新属性、新事件等一律使用undefined而非null;部分内部实现也从null切换到undefined。旧属性大多保持null不变,但要注意:部分内部改动可能已波及外部属性/事件/方法的取值,迁移测试时建议覆盖此类边界。

Deprecations:弃用项的处理策略

大部分变更都保留了旧函数与旧属性,但统一标记为@deprecated。官方立场明确:

  • 强烈建议应用重构以摆脱弃用项;
  • 与弃用项相关的缺陷会被赋予低优先级(或完全不修复);
  • 弃用的别名、方法、属性可能在未来的版本中被移除。

因此迁移不应停留在"能跑就行",而应把消灭弃用告警作为正式目标。

Public 与 Internal API 边界

v2 中所有 API 元素(类、接口、函数等)都被标注为public或internal:

  • 应用只能使用publicAPI 元素;
  • internal元素随时可能变化,变更时不做任何向后兼容承诺。

库分发包含两份 TypeScript 声明(.d.ts)文件:

  1. index.d.ts:只包含 public API 元素。应用应使用这份声明文件访问库;
  2. golden-layout-untrimmed.d.ts:包含全部(public + internal)API 元素。若确需访问库内任意元素可使用它,但请充分知悉上述风险。

官方同时说明:public/internal 的划分尚未最终定型,但任何在apitest演示程序或 Angular 示例应用中使用过的元素,都会保持为 public——这为迁移者提供了一个"安全区"判断依据。

迁移检查清单

综合全文,从 v1 迁移到 v2 时建议按以下顺序核对:

  1. 确认不依赖已移除特性(React 支持、嵌套 Stack、jQuery、旧浏览器);
  2. 构造函数改为new GoldenLayout(container),布局通过loadLayout()加载;
  3. 将registerComponent()改为registerComponentConstructor()/registerComponentFactoryFunction();
  4. 把toConfig()→saveLayout()、updateSize()→setSize()、root→rootItem、minifyConfig()/unminifyConfig()→ResolvedLayoutConfig上同名方法;
  5. 配置中把componentName改为componentType,width/height/minWidth/minHeight改为size/minSize,确认root已指定、id为string;
  6. 持久化:保存saveLayout()返回的 Resolved Config,加载前用LayoutConfig.fromResolved()转换;
  7. 用ComponentItem.focus()/blur()替代select()/deselect(),用Stack.getActiveComponentItem()替代旧命名;
  8. 把getElement()改为element属性,评估是否迁移到stateRequestEvent与beforeComponentRelease;
  9. 组件绑定优先采用bindComponentEvent/unbindComponentEvent(见 绑定组件文档),并处理stackHeaderClick等新事件;
  10. 全程只使用 public API,以index.d.ts为准,消灭所有@deprecated告警。

仓库中的 apitest 演示程序与 规格测试(如 drag-tests.ts、ground-item-tests.ts)是观察 v2 新 API 实际用法的最佳样例,迁移过程中可随时对照查阅。

  • 前端
  • UI组件

【免费下载链接】golden-layout

A multi window layout manager for webapps

项目地址:https://gitcode.com/gh_mirrors/go/golden-layout
点击查看免费下载
上一篇:从8位到32位:如何用STM32F103VET6打造高性能CNC控制器?
下一篇:comprehensive-rust 泛型精讲:Trait Bounds(特质约束)从语法到编译原理

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 2:15:15

DeepSeek本地部署全指南:显存计算、量化选型与推理框架调优

简介&#xff1a;一份DeepSeek大语言模型本地部署教程&#xff0c;面向具有一定计算机基础、希望实现数据本地化处理或模型二次开发的技术人员。教程完整覆盖安装前准备、部署方案选择、可视化界面配置、验证与测试、常见问题与解决方案、安全与性能优化建议等环节&#xff1a;…

作者头像 李华
网站建设 2026/10/7 2:13:25

排序全解析:算法、工程与应用的三个核心层面

如果只看标题“排序------3”&#xff0c;你可能会觉得这是一个随手记的草稿&#xff1a;不知道“3”是第几版&#xff0c;也不知道为什么要用三个横杠隔开。但恰恰是这种模糊的标题&#xff0c;反而把一个被大多数人当成“理所当然”的技术话题重新推到了台前。排序这件事&…

作者头像 李华
网站建设 2026/10/7 2:12:55

代理记账许可证编号怎么查?DLJZ 编号含义与查验方法

代理记账许可证编号怎么查&#xff1f;DLJZ 编号含义与查验方法 一分钟看答案 正规代理记账机构的《代理记账许可证书》编号以 DLJZ 开头&#xff08;DL代理&#xff0c;JZ记账&#xff09;&#xff0c;后面是地区行政区划码、核发年份和流水号。查验只要三步&#xff1a; 要编…

作者头像 李华
网站建设 2026/10/7 2:11:16

AI工作流实战:WorkBuddy技能封装与本地化搭建指南

如果你最近在关注 AI 工作流&#xff0c;可能会发现一个现象&#xff1a;Coze、Dify、n8n 这类工具已经把“搭建工作流”讲得很透了&#xff0c;教程遍地都是&#xff0c;但真正落到自己项目里的却不多。原因倒不难理解——很多演示停留在“拖几个节点、点一下运行、截图发朋友…

作者头像 李华