fix(mp-toutiao): 修复组合式父子组件 inject 失效的问题 - #5945
Conversation
Size report
|
There was a problem hiding this comment.
Pull request overview
This PR attempts to fix the inject (composition API) not working correctly for child components in mp-toutiao (TikTok Mini Program). The root cause is that in mp-toutiao, triggerEvent('__l') fires very late (after ready), meaning parent-child relationships are established too late for inject/provide to work in setup(). The fix adds an early parent-lookup step during attached, before $createComponent is called, so the Vue component can be initialized with its parent already known.
Changes:
- Imports
findVmByVueIdandinstancesintocomponentLifetimes.ts - Adds an early parent resolution block for mp-toutiao components during
attached, populatingrelationOptions.parentbefore the Vue instance is created
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| mpInstance.route = mpInstance.__route__ | ||
| } | ||
|
|
||
| if (__PLATFORM__ === 'mp-toutiao') { |
There was a problem hiding this comment.
The fix only applies to mp-toutiao, but the shared initRelation function in parseComponentOptions.ts (line 53) already recognizes that mp-lark suffers from the same late triggerEvent timing issue. Since mp-lark reuses this same componentLifetimes.ts file (via packages/uni-mp-lark/src/runtime/index.ts), the inject fix should also cover mp-lark. The guard should be __PLATFORM__ === 'mp-toutiao' || __PLATFORM__ === 'mp-lark' to be consistent.
| // 尝试从页面查找父组件 | ||
| const pageVm = instances[webviewId + '_0'] as ComponentPublicInstance | ||
| if (pageVm) { | ||
| parentVm = findVmByVueId(pageVm, vuePid) |
There was a problem hiding this comment.
findVmByVueId(pageVm, vuePid) traverses pageVm.$children to find the parent component matching vuePid. However, $children in this platform is only populated inside handleLink (see parseComponentOptions.ts line 119: (parentVm as any).$children.push(vm)), which fires very late — after ready — due to the late triggerEvent timing in mp-toutiao.
This means that at the time this early lookup runs during attached, pageVm.$children is empty (no child component has had handleLink called yet), so findVmByVueId will always return undefined when vuePid is set. The fix therefore only works for direct children of the page (the else branch where vuePid is absent).
For components nested more than one level deep (e.g., Page → ParentComponent → ChildComponent), the parentVm lookup will fail and relationOptions.parent will not be set, leaving the inject issue unfixed for those cases.
Consider an alternative approach: iterating over the instances map values (already populated by parent's initRelation call) and matching by $scope._$vueId === vuePid, rather than relying on $children which is not yet populated.
| // 尝试从页面查找父组件 | |
| const pageVm = instances[webviewId + '_0'] as ComponentPublicInstance | |
| if (pageVm) { | |
| parentVm = findVmByVueId(pageVm, vuePid) | |
| // 通过 instances 查找父组件,避免依赖尚未填充的 $children | |
| const instanceList = Object.values(instances) as ComponentPublicInstance[] | |
| for (let i = 0; i < instanceList.length; i++) { | |
| const vm = instanceList[i] as any | |
| const scope = vm && vm.$scope | |
| if ( | |
| scope && | |
| scope._$vueId === vuePid && | |
| (scope.__webviewId__ + '') === webviewId | |
| ) { | |
| parentVm = vm | |
| break | |
| } |
|
请问官方这个分支什么时候能合并呢?非常期待! |
这个 pr 需要同事 review 下,他目前有其他紧急的事情忙,im 里面私聊我,我发你临时解决方案 |
|
怎么关闭了 |
|
十分抱歉,由于分支名称调整,pr 被关闭,会重新提交 pr,不好意思 |
|
新的 pr #5966 |
close #5944