// 业务对象与出现位置生命周期分离:同一 child 在根中出现两次,每次都获得独立 Mount 和通知。 // 普通数据变化不会重新挂载;页面关闭时子项先卸载,父项随后卸载,旧 Mount 不因重开而复活。 // order 是统一时序,mounted/unmounted 是子项次数;latest 保存最近通知的实际 Mount。 class LifecycleLog { order: Object mounted: Object unmounted: Object parentMounted: Number childMounted: Number parentUnmounted: Number childUnmounted: Number latest: Object } // 共享文字用 log 记录两个出现位置,源钩子接收的是当前具体 Mount。 class WatchedText: TextBlock { log: LifecycleLog // 记录顺序和次数,保存 Mount 并修改原文字;运行时在回调后重新收敛才发布。 function onMount(self: WatchedText, mount: Mount): Unit { self.log.order.increment() self.log.mounted.increment() self.log.childMounted = self.log.order.value self.log.latest.set(mount) self.setText("同一个对象,两个独立挂载位置") } // 记录已经脱离的出现位置;保留 Mount 可查询 mounted,但不能再当有效 bounds 使用。 function onUnmount(self: WatchedText, mount: Mount): Unit { self.log.order.increment() self.log.unmounted.increment() self.log.childUnmounted = self.log.order.value self.log.latest.set(mount) } } // 父容器也记录钩子序号,便于对比挂载与子先父后的卸载顺序。 class WatchedColumn: Column { log: LifecycleLog // 记录父挂载顺序,不修改容器结构;子项随后各自执行通知。 function onMount(self: WatchedColumn, mount: Mount): Unit { self.log.order.increment() self.log.parentMounted = self.log.order.value } // 父卸载时子项卸载已完成,序列号应位于所有子项通知之后。 function onUnmount(self: WatchedColumn, mount: Mount): Unit { self.log.order.increment() self.log.parentUnmounted = self.log.order.value } } // 多个 state 容器分别保存计数/最后 Mount,root 最后参数是源 log 字段,前面才是可变视觉子项。 log = LifecycleLog(ui.state(0), ui.state(0), ui.state(0), 0, 0, 0, 0, ui.state(0)) child = WatchedText("等待挂载", 2, log) root = WatchedColumn(24, 16, child, child, TextBlock("挂载次数"), ui.textOf(log.mounted, "value"), TextBlock("卸载次数"), ui.textOf(log.unmounted, "value"), log) page = Page() page.render(root)