UI 管理器

模块管理器负责模块的注册、打开、关闭、对象池管理与生命周期调度

mk.uiManage 是整个 UI 模块系统的核心管理器。它负责:

  • 模块的 注册 / 取消注册 / 自动注册
  • 模块的 打开 / 关闭 / 获取(支持按类型、按实例、按节点操作)
  • 内置 对象池(Prefab/Node 复用)以减少频繁创建销毁开销
  • 模块 重复加载保护模块栈管理(支持单独展示/隐藏逻辑)
  • 与全局事件(如重启)联动,负责资源与状态清理

概念#

使用方式#

mk.uiManage 需要先注册模块(regis),才能打开模块(open)

注册是为了保存模块只需要传递一次的数据,同时进行创建对象池并预加载对象

属性#

event#

UI 事件对象,提供如下事件

事件名参数描述
open(key: mk.UIManage.TypeOpenKey, module_: any)模块成功打开后触发
close(key: mk.UIManage.TypeOpenKey, module_: any)模块成功关闭后触发

用例:

mk.uiManage.event.on(mk.uiManage.event.key.open, (key_: mk.UIManage_.TypeOpenKey, module_: any) => {
    ...
}, this)

getRegisDataFunc#

获取模块注册数据方法,如果你不想要每个地方都使用 mk.uiManage.regis,你可以赋值给这个属性一个函数, 根据参数(mk.ViewBase 构造类型)返回对应的注册数据

它将在 mk.uiManage.open 没有获取到注册数据时被调用


方法#

regis#

regis(key, source, target?, config?) : Promise<void>

注册模块并初始化对象池。

参数#

  • key:模块类型(Constructor<mk.ViewBase>
  • source:注册资源来源(Prefab | string | Node | Record<type, Prefab|string|Node>
  • target资源跟随释放对象
  • config:可选,注册配置
  • config.isRepeat:此模块是否可以创建多个,默认 false
  • config.parent:此模块的默认父节点,默认 canvas 节点,不存在则为 scene
  • config.loadConfig:加载资源时传给 mk.asset.get 的配置
  • config.poolMinHoldNum:对象池最小保留数量(不足时扩充数),默认 isRepeat ? 8 : 1
  • config.poolMaxHoldNum:对象池最大保留数量(-1 表示不启用),默认 -1
  • config.poolInitFillNum:对象池初始化填充数量,默认 1

要点#

  • source 可以传递 Record 对象用于代表不同类型的资源来源(参见下方示例)
  • 如果传入 target,则由 target 控制何时触发 unregis(key)

示例#

// 通过资源路径注册 Test 模块
await mk.uiManage.regis(Test, 'Module/Test/Test111.prefab', this);
// 通过资源路径注册多类型 Test 模块
await mk.uiManage.regis(
    Test,
    {
        default: 'Module/Test/Test111.prefab',
        type2: 'Module/Test/Test222.prefab',
    },
    this
);

unregis#

unregis(key) : Promise<void>

取消注册模块并清理相关资源:

  • 会等待正在进行的注册任务完成(若有)。
  • 自动 close 所有该模块实例(isAll: true, isDestroy: true)。
  • 销毁并释放对象池中节点及其可能动态加载的 Prefab 引用。
  • 从内部映射中移除注册信息。

如果注册时传入了 target(跟随释放对象),一般无需手动调用 unregis,除非你想提前释放。

参数#

  • key:模块类型(Constructor<mk.ViewBase>

get#

get() / get(key) / get(key, type)

参数#

  • 空参数:获取当前所有打开的模块

  • key

    • Constructor<mk.ViewBase>,返回最后打开的模块实例
    • [Constructor<mk.ViewBase>],返回所有打开的模块实例列表
  • type:筛选结果,模块 typeStr === type

示例#

// 获取当前所有打开的 ViewBase 对象
const all = mk.uiManage.get();
// 获取最后打开的 Test 模块
const test = mk.uiManage.get(Test);
// 获取所有打开的 Test 模块列表
const testList = mk.uiManage.get([Test]);
// 获取最后打开的 Test 模块且模块类型为 default
const panelOfTypeA = mk.uiManage.get(Test, 'default');
// 获取所有打开的 Test 模块列表且模块类型为 default
const panelOfTypeAList = mk.uiManage.get([Test], 'default');

open#

open(key, config?) : Promise<module | null>

打开模块,需要模块已经调用 regisgetRegisDataFunc 参数存在

参数#

  • key:模块类型(Constructor<mk.ViewBase>
  • config:可选,打开配置
  • config.init:初始化数据,和 key 类型的成员属性 initData 类型一致
  • config.type:模块类型,默认 "default"
  • config.parent:模块父节点

要点#

  • 你可以在调用 regis 后立即 open(不必等待 regis 完成)

示例#

const test = await mk.uiManage.open(Test, { init: { id: 1 }, type: 'default' });

close#

close(args, config?) : Promise<boolean>

关闭模块

参数#

  • args:可以是 Node / Constructor<mk.ViewBase> / mk.ViewBase 实例
  • config:可选,关闭配置
  • config.type:模块类型,默认值 default
  • config.isAll:关闭全部模块,默认值 false
  • config.isDestroy:销毁节点,默认值 false
  • config.isDestroyChildren:销毁动态子节点(动态子节点是通过 mk.uiManage.open 加载到模块节点下的其他模块),默认值 isDestroy

要点#

  • 若 isDestroy 为 false 则会回收模块节点而不是 destroy

示例#

// 关闭 Test 模块(最后打开的模块)
await mk.uiManage.close(Test);
// 关闭所有的 Test 模块
await mk.uiManage.close(Test, { isAll: true });
// 关闭并销毁 Test 模块,并且销毁所有加载到 Test 节点下的模块
await mk.uiManage.close(Test, { isDestroy: true, isDestroyChildren: true });

实用示例#

注册并打开模块:

// 手动注册
await mk.uiManage.regis(Test, 'Module/Test/Test.prefab', this);

// 打开
const test = await mk.uiManage.open(Test, { init: { id: 1 } });

// 关闭并销毁最近打开的 Test
await mk.uiManage.close(Test, { isDestroy: true });

监听模块打开/关闭事件:

mk.uiManage.event.on(mk.uiManage.event.key.open, (key, instance) => {
    console.log('opened:', key.name, instance);
});
mk.uiManage.event.on(mk.uiManage.event.key.close, (key, instance) => {
    console.log('closed:', key.name, instance);
});

注意与最佳实践#

  • 提前通过 regis 注册资源,避免 open 时才首次加载导致的卡顿;若使用动态注册,请实现 getRegisDataFunc 以支持自动注册。
  • isRepeat=false(默认)时,打开策略会避免重复打开:当已有实例或正在打开时会返回 null。若需要多个同类实例(例如列表中的多个 item),请将 isRepeat 设为 true
  • RegisConfig.poolInitFillNum 设置过大可能在注册时导致大量预加载,注意资源占用。
  • 如果模块资源跟随某对象生命周期(例如 bundle / 外部资源),优先将该对象作为 registarget 传入,框架会在 target 释放时自动取消注册并回收资源。