Skip to content

fix(runtime-vapor): v-show on a Vapor child dropped on a root change, lost after a non-element root - #15566

Open
ValentinYoushkevich wants to merge 1 commit into
vuejs:minorfrom
ValentinYoushkevich:fix/vapor-interop-directive-root
Open

ValentinYoushkevich wants to merge 1 commit into
vuejs:minorfrom
ValentinYoushkevich:fix/vapor-interop-directive-root

Conversation

@ValentinYoushkevich

Copy link
Copy Markdown

A VDOM directive on a Vapor child never sees the child's own re-render — no beforeUpdate, no updated — and when the child swaps its root element the directive does not follow it, so a child with v-show="false" paints visible. Once the root stops being an element the bindings are gone for good.

https://play.vuejs.org/#eNrtlU1v2zAMhv8K4R3cAom9LxRd5njr1gHtYbu0GzAgwKpYbK3VkQRJcRIE+e+j5I85wZAVO++UkKYfUi8pehtdaJ3US4wmUWYLI7QDi26p85kUC62Mgy1YpwzCDu6NWkCcpMFOftq4j/nG6OdjKSreB/12efwglKvFQWTnaQOztCmESiDD4UJXzCFZAJnOPyhXQuHDDUp4QAdZoTjm9diWajWdRfessjiLsjS4myyuFBZqygOa0WtuBFZ5HsDc4+ZqjRYWS0uHd2wDlNJtYFVS2hoNbNQStEFrkyzVTR3zpXNKwvuiEsUjJW0kMUo5mMLQmE4h5qKO4R3EOoZJY82i3K6YproQQhxWuKC6srQBPyFJ7HDtPIgbRSAFDLwn4EYeLCGkmLPicR+r89r3phGxPxGVBUXFrKVEpAeBs0FXD9WFNM9SeqUnem3/Dux7f4SXpYOWk2ndpvJ/E4LA1qPnynA0E3ih19THSnB4dn5+/tY/Wgg5LlE8lG4CL8/0Ojg141zIhwm8Do5dGLGWGo2i/Uk9vAgQxHridTg2ul6PeizuDxrZDQjpc3t1fQOfv97cws3txXe4ur68/PQFTvyLPvZ0qDihkJT7M08foemO1bapK7IF5lJ1wxgCJ80NsYLTDWlGjWaWC4OFEzVCiQZHwCzgWpML+V779gwv9fCq/+PK+a/xcY07qUjeXk6DrEF1ijabdibTFJSsNiFhv1QpmsOdr+zOL0raLO0mCkuQHo8pim4gFcSKdhkTJtCEs6BWEpjkIMP2HITTt2Ym6RC+qELJsG59n6d9gSfbVpFmae5Ow5F+EMcKJelIr5Kz5PnYFMmbaPcL+0RMYg==

VDOM inherits a component's directives onto the rendered root vnode, so they follow that root through every patch and every replacement. I made the interop follow the child's effective root the same way, releasing the old element while it is still in the document and mounting onto the one that replaced it.

Two divergences stay: created and beforeMount run after insertion here, so a v-show root swap still flashes for one frame, and the beforeUpdate that already fires on a root about to be replaced remains — a Vapor root is only known once the child has rendered.

@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 6c508b69-4fcb-45cc-8adf-5994e60c085d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Sep 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@15566
npm i https://pkg.pr.new/@vue/compiler-core@15566
yarn add https://pkg.pr.new/@vue/compiler-core@15566.tgz

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@15566
npm i https://pkg.pr.new/@vue/compiler-dom@15566
yarn add https://pkg.pr.new/@vue/compiler-dom@15566.tgz

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@15566
npm i https://pkg.pr.new/@vue/compiler-sfc@15566
yarn add https://pkg.pr.new/@vue/compiler-sfc@15566.tgz

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@15566
npm i https://pkg.pr.new/@vue/compiler-ssr@15566
yarn add https://pkg.pr.new/@vue/compiler-ssr@15566.tgz

@vue/compiler-vapor

pnpm add https://pkg.pr.new/@vue/compiler-vapor@15566
npm i https://pkg.pr.new/@vue/compiler-vapor@15566
yarn add https://pkg.pr.new/@vue/compiler-vapor@15566.tgz

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@15566
npm i https://pkg.pr.new/@vue/reactivity@15566
yarn add https://pkg.pr.new/@vue/reactivity@15566.tgz

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@15566
npm i https://pkg.pr.new/@vue/runtime-core@15566
yarn add https://pkg.pr.new/@vue/runtime-core@15566.tgz

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@15566
npm i https://pkg.pr.new/@vue/runtime-dom@15566
yarn add https://pkg.pr.new/@vue/runtime-dom@15566.tgz

@vue/runtime-vapor

pnpm add https://pkg.pr.new/@vue/runtime-vapor@15566
npm i https://pkg.pr.new/@vue/runtime-vapor@15566
yarn add https://pkg.pr.new/@vue/runtime-vapor@15566.tgz

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@15566
npm i https://pkg.pr.new/@vue/server-renderer@15566
yarn add https://pkg.pr.new/@vue/server-renderer@15566.tgz

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@15566
npm i https://pkg.pr.new/@vue/shared@15566
yarn add https://pkg.pr.new/@vue/shared@15566.tgz

vue

pnpm add https://pkg.pr.new/vue@15566
npm i https://pkg.pr.new/vue@15566
yarn add https://pkg.pr.new/vue@15566.tgz

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@15566
npm i https://pkg.pr.new/@vue/compat@15566
yarn add https://pkg.pr.new/@vue/compat@15566.tgz

commit: ee37a54

@github-actions

github-actions Bot commented Sep 18, 2026

Copy link
Copy Markdown

Size Report

Bundles

File Size Gzip Brotli
compiler-dom.global.prod.js 87.2 kB 30.6 kB 26.9 kB
runtime-dom.global.prod.js 117 kB 44 kB 39.5 kB
vue.global.prod.js 177 kB 64.1 kB 57.1 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 53.8 kB 20.8 kB 19 kB
createApp 62.5 kB 24 kB 21.9 kB
createApp + vaporInteropPlugin 123 kB (+876 B) 44.2 kB (+289 B) 39.7 kB (+221 B)
createVaporApp 30.8 kB 11.8 kB 10.9 kB
createSSRApp 67.7 kB 26.1 kB 23.7 kB
createVaporSSRApp 37.2 kB 14.1 kB 12.9 kB
defineCustomElement 69.1 kB 26 kB 23.7 kB
defineVaporCustomElement 46.2 kB 16.8 kB 15.4 kB
overall 78.1 kB 29.6 kB 26.8 kB

@ValentinYoushkevich

Copy link
Copy Markdown
Author

I see the interop paths are being reworked right now (#15567, #15568) — let me know if this collides with anything in flight and I'll rebase out of your way.

For what it's worth, this one deliberately stays on the existing path: it doesn't restructure the interop, it only makes the child's effective root be followed the way vdom already follows a component's inherited directives.

If a smaller diff is easier to take, I'm happy to split it — the missing beforeUpdate/updated on a stable root is independent of the root-swap half, and either can go on its own. Equally fine if you'd rather fold it into your own work.

@edison1105

Copy link
Copy Markdown
Member

@ValentinYoushkevich
Thanks! Please rebase this onto the latest minor. I haven’t had a chance to review it yet, but there’s no need to split the PR.

If the overall approach looks good, I’ll either merge it as-is or make some adjustments first. If I come up with a better implementation, I’ll open a separate PR.

@edison1105 edison1105 added the scope: vapor related to vapor mode label Sep 20, 2026
@ValentinYoushkevich
ValentinYoushkevich force-pushed the fix/vapor-interop-directive-root branch from f80f6de to ee37a54 Compare September 20, 2026 10:43
@ValentinYoushkevich

Copy link
Copy Markdown
Author

Rebased onto f1c66a970 — no conflicts, the patch is unchanged. Tests green on the new base.

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

Labels

scope: vapor related to vapor mode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants