Skip to content

fix(mp): dynamic slot names when v-if wraps v-slot#6012

Open
Jefsky wants to merge 1 commit into
dcloudio:nextfrom
Jefsky:fix/mp-slot-conditional-vif
Open

fix(mp): dynamic slot names when v-if wraps v-slot#6012
Jefsky wants to merge 1 commit into
dcloudio:nextfrom
Jefsky:fix/mp-slot-conditional-vif

Conversation

@Jefsky

@Jefsky Jefsky commented Jun 9, 2026

Copy link
Copy Markdown

根因

v-if(或 v-else-if/v-else)包裹 <template v-slot> 时,编译产物仍然静态地声明 slot 名称(u-s="{{['body']}}")。运行时无论条件是否成立,都会设置 $slots.body = true,导致父组件认为 slot 一定有内容。

在微信小程序中,这会让 ref 拿到的 slotted 组件实例为 null,因为 slot 实际被 wx:if 隐藏了。

修复方法

  1. 编译器 (vSlot.ts):检测 slot 模板上的 v-if/v-else-if/v-else 指令,生成动态 slot 名称数组。例如:

    • u-s="{{c}}" 而不是 u-s="{{['body']}}"
    • render 输出加 { c: [ok ? 'body' : ''] }
    • 支持多分支条件链(v-if + v-else-if + v-else
  2. 运行时 (componentProps.ts):

    • observerSlots 中跳过空字符串 slot 名(条件为 false 时产生的)
    • $vm 存在时同步 $vm.$.slots$forceUpdate()
  3. 测试:更新 mp-compiler、mp-alipay、mp-baidu 三个平台的 vSlot.spec.ts,新增 13 个 v-if/v-else-if/v-else + v-slot 组合测试用例。

测试方法

# 编译器单测
cd packages/uni-mp-compiler && npm test
cd packages/uni-mp-alipay && npm test
cd packages/uni-mp-baidu && npm test

也可用 issue #5513 中的 demo-1/demo-2 复现包验证微信小程序行为。

备注

这个修复基于 maintainer @chouchouji 之前在 #5622 中提交的方案(因目标分支被删除而关闭)。代码已适配当前 next 分支。

Fixes #5513

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
@chouchouji

Copy link
Copy Markdown
Member

这个改动有点大,目前还在寻找更合理的解决方案。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants