fix(mp): dynamic slot names when v-if wraps v-slot#6012
Open
Jefsky wants to merge 1 commit into
Open
Conversation
When v-if (or v-else-if / v-else) wraps a <template v-slot>, the
compiled output still statically declares the slot name in u-s.
The runtime then sets $slots.<name> = true regardless of the
condition, so the parent thinks the slot is provided even when the
conditional hides it. This causes refs to slotted components to
return null in WeChat Mini Program.
Generate dynamic slot name arrays keyed on the condition expression,
e.g. u-s="{{c}}" with { c: [ok ? 'body' : ''] } in the render
output. On the runtime side, skip empty slot names and sync
$vm.$.slots + force update when uS changes.
Fixes dcloudio#5513
Member
|
这个改动有点大,目前还在寻找更合理的解决方案。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
根因
当
v-if(或v-else-if/v-else)包裹<template v-slot>时,编译产物仍然静态地声明 slot 名称(u-s="{{['body']}}")。运行时无论条件是否成立,都会设置$slots.body = true,导致父组件认为 slot 一定有内容。在微信小程序中,这会让
ref拿到的 slotted 组件实例为null,因为 slot 实际被wx:if隐藏了。修复方法
编译器 (
vSlot.ts):检测 slot 模板上的v-if/v-else-if/v-else指令,生成动态 slot 名称数组。例如:u-s="{{c}}"而不是u-s="{{['body']}}"{ c: [ok ? 'body' : ''] }v-if+v-else-if+v-else)运行时 (
componentProps.ts):observerSlots中跳过空字符串 slot 名(条件为 false 时产生的)$vm存在时同步$vm.$.slots并$forceUpdate()测试:更新 mp-compiler、mp-alipay、mp-baidu 三个平台的
vSlot.spec.ts,新增 13 个 v-if/v-else-if/v-else + v-slot 组合测试用例。测试方法
也可用 issue #5513 中的 demo-1/demo-2 复现包验证微信小程序行为。
备注
这个修复基于 maintainer @chouchouji 之前在 #5622 中提交的方案(因目标分支被删除而关闭)。代码已适配当前
next分支。Fixes #5513