小程序基础库版本要求:
基础库版本 > 2.25.4 时可复现
基础库版本 <= 2.25.4 时表现正常
问题描述及复现步骤:
1) 项目结构,项目分主包和分包(如下图),其中:
主包包含一些公共的,同步的基础组件,如 comp1、comp2、comp3
分包包含一些业务的异步组件,如 async-comp1、async-comp2、async-comp3 ... async-comp7
2) 页面结构,包含页面元素、同步组件、异步组件,如下图:
2.1 所有的异步组件在组件的 attached 生命周期中抛出事件 this.triggerEvent('attached')
2.2 在页面所有的异步组件上监听 attached 事件并进行处理
当事件处理器以同步的方式调用 setData 时,会导致部分异步组件的 attached 生命周期不触发,
如下图控制台 AppData 中可以看到,async-comp2、async-comp4、async-comp6 组件的 attached 生命周期不触发,在实际复杂的项目里,会直接表现为组件加载失败。
加载失败的组件表现出一定的规律,async-comp2为第一个监听 attached 事件的后一个组件,async-comp4、async-comp6 组件前都有一个同步组件。
当事件处理器以异步的方式调用 setData 时,或小程序基础库版本 <= 2.25.4 时,表现正常,如图:
针对已上问题,如果是bug,希望官方能够及时修复或者给出解决方案,如果是 feature,麻烦说明其中原理,谢谢!
感谢反馈,很清晰的片段~
我们排查到这里出问题的原因是目前的占位组件替换逻辑对相关组件的生命周期的触发时序处理不对,表现为组件 attached 或子组件 moved 生命周期触发时,组件节点树处于一个不正确的临时态,导致此时(attached 生命周期中)同步的 setData 引发的模板 diff 无法正确同步到节点树上,从而在后续的流程中创建了错误的替换组件,并在错误的组件上触发了 attached 周期,最终出现片段中的问题。
这段逻辑在基础库 2.26.1 版本引入,目的是修复更早版本中的另一个问题(子组件会先触发 detached 再触发 attached,而不是触发 moved)。我们会尽快处理修复这个问题,再次感谢~
貌似已经修复了
根据你的代码,并未复现
async-comp2 attached、
async-comp4 attached、
async-comp6 attached
同时,切换到 AppData 中,也能看到没有:
hasAsyncComp2Attached、
hasAsyncComp4Attached、
hasAsyncComp6Attached