Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix(runtime-core): pass props and children to loadingComponent #13997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
indykoning wants to merge 2 commits into vuejs:main
base: main
Choose a base branch
Loading
from indykoning:patch-1

Conversation

@indykoning
Copy link

@indykoning indykoning commented Oct 17, 2025
edited by coderabbitai bot
Loading

This PR offers some backwards compatibility with Vue 2

In some cases you will want to use passed properties and children to the loading component, this was possible in Vue 2 but not in Vue 3. This PR gets you that ability back.


For some background, i have a heavy autocomplete bar requiring some big libraries which i do not want to load unless the autocomplete gets used.

For this i've created an async component that gets loaded after an event gets fired. This event would get fired when focussing on the "facade" input:

vue.component('autocomplete', defineAsyncComponent({
 loader: () => new Promise(function (resolve, reject) {
 document.addEventListener('loadAutoComplete', () => import('./components/Search/Autocomplete.vue').then(resolve), {'once': true})
 }),
 loadingComponent: {
 data: () => ({
 loaded: false,
 }),
 render() {
 return this.$slots.default(this)
 },
 },
 delay: 0,
}))
<autocomplete v-slot="{ loaded, ... }">
 <form method="GET" action="/search">
 <input 
 type="search" 
 v-on:focus="window.document.dispatchEvent(new window.Event('loadAutoComplete'))"
 ...
 />
 <heavy-search-library v-if="loaded">
 ...
 </heavy-search-library>
 </form>
</autocomplete>

This worked perfectly in Vue 2, however with Vue 3 this results in this.$slots.default is not a function which makes sense because the loadingComponent does not actually get access to their props and children.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed async component loading state to properly inherit context during the pending load phase, ensuring the loading UI displays correctly.

Copy link

coderabbitai bot commented Oct 17, 2025
edited
Loading

Walkthrough

The async component loading path now wraps the resolved loading component with createInnerComp(resolved) instead of creating a vnode directly, so the loading component is instantiated as an inner component and receives the async wrapper's context (refs, custom element hooks, props).

Changes

Cohort / File(s) Summary
Async Component Loading State
packages/runtime-core/src/apiAsyncComponent.ts
Replace direct createVNode(loadingComponent) with createInnerComp(resolved) for the loading state so the loading component inherits the async wrapper's context

Sequence Diagram(s)

sequenceDiagram
 autonumber
 participant App as App
 participant AsyncWrapper as AsyncWrapper
 participant Resolver as Resolver
 participant InnerComp as createInnerComp
 participant Loading as LoadingComponent
 App->>AsyncWrapper: render async component
 AsyncWrapper->>Resolver: resolve loadingComponent (pending)
 Resolver-->>AsyncWrapper: loadingComponent (resolved)
 note right of AsyncWrapper #E6F7FF: New: wrap resolved\nwith createInnerComp
 AsyncWrapper->>InnerComp: createInnerComp(resolved)
 InnerComp->>Loading: instantiate as inner component
 Loading-->>App: render (inherits wrapper context)
Loading

(Optional comparison — old flow)

sequenceDiagram
 autonumber
 participant AsyncWrapper as AsyncWrapper
 participant Resolver as Resolver
 participant VNode as createVNode
 participant Loading as LoadingComponent
 AsyncWrapper->>Resolver: resolve loadingComponent (pending)
 Resolver-->>AsyncWrapper: loadingComponent (resolved)
 note right of AsyncWrapper #FFF4E6: Old: direct vnode creation
 AsyncWrapper->>VNode: createVNode(loadingComponent)
 VNode->>Loading: instantiate as standalone vnode (no wrapper context)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested labels

:hammer: p3-minor-bug

Poem

🐇
I wrap the spinner snug and tight,
So props and refs feel just right.
As async waits and banners hum,
The inner bloom inherits come—
A tiny hop, a smoother sight.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "fix(runtime-core): pass props and children to loadingComponent" directly and accurately describes the main change in the changeset. The summary shows that the modification enables the loadingComponent to inherit context including props and children by wrapping it with createInnerComp(resolved), which is exactly what the title conveys. The title is concise, clear, uses the project's conventional formatting with the fix prefix, and contains no vague or noise-inducing terms. It aligns well with the PR's stated objective of restoring Vue 2 backwards compatibility by allowing async components' loadingComponent to receive props and slots.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9498a8b and 702adcb.

📒 Files selected for processing (1)
  • packages/runtime-core/src/apiAsyncComponent.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/runtime-core/src/apiAsyncComponent.ts

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 and usage tips.

@edison1105 edison1105 changed the title (削除) Pass props and children to loadingComponent (削除ここまで) (追記) fix(runtime-core): pass props and children to loadingComponent (追記ここまで) Oct 17, 2025
@edison1105 edison1105 added ready to merge The PR is ready to be merged. 🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. labels Oct 17, 2025
Copy link

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 102 kB (+2 B) 38.6 kB (+2 B) 34.8 kB (+13 B)
vue.global.prod.js 160 kB (+2 B) 58.7 kB (+2 B) 52.2 kB (-1 B)

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.7 kB 18.3 kB 16.7 kB
createApp 54.7 kB 21.3 kB 19.5 kB
createSSRApp 58.9 kB 23 kB 21 kB
defineCustomElement 60 kB 23 kB 21 kB
overall 68.8 kB 26.5 kB 24.2 kB

Copy link

pkg-pr-new bot commented Oct 17, 2025

Open in StackBlitz

@vue/compiler-core
npm i https://pkg.pr.new/@vue/compiler-core@13997
@vue/compiler-dom
npm i https://pkg.pr.new/@vue/compiler-dom@13997
@vue/compiler-sfc
npm i https://pkg.pr.new/@vue/compiler-sfc@13997
@vue/compiler-ssr
npm i https://pkg.pr.new/@vue/compiler-ssr@13997
@vue/reactivity
npm i https://pkg.pr.new/@vue/reactivity@13997
@vue/runtime-core
npm i https://pkg.pr.new/@vue/runtime-core@13997
@vue/runtime-dom
npm i https://pkg.pr.new/@vue/runtime-dom@13997
@vue/server-renderer
npm i https://pkg.pr.new/@vue/server-renderer@13997
@vue/shared
npm i https://pkg.pr.new/@vue/shared@13997
vue
npm i https://pkg.pr.new/vue@13997
@vue/compat
npm i https://pkg.pr.new/@vue/compat@13997

commit: 9498a8b

Copy link
Member

edison1105 commented Oct 17, 2025
edited
Loading

Thanks for the PR. It would be better if you added a test case.

Co-authored-by: edison <daiwei521@126.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@edison1105 edison1105 edison1105 left review comments

Assignees

No one assigned

Labels

🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. ready to merge The PR is ready to be merged.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /