Skip to content

Commit 19ef115

Browse files
xanfcexbrayat
authored andcommitted
fix: allow finding async component stubs by definition
1 parent 7277cc5 commit 19ef115

File tree

4 files changed

+73
-16
lines changed

4 files changed

+73
-16
lines changed

src/vnodeTransformers/stubComponentsTransformer.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import {
1111
ConcreteComponent,
1212
ComponentPropsOptions,
1313
ComponentObjectPropsOptions,
14-
DefineComponent,
15-
Component
14+
Component,
15+
ComponentOptions
1616
} from 'vue'
1717
import { hyphenate } from '../utils/vueShared'
1818
import { matchName } from '../utils/matchName'
@@ -28,6 +28,7 @@ import { registerStub } from '../stubs'
2828
export type CustomCreateStub = (params: {
2929
name: string
3030
component: ConcreteComponent
31+
registerStub: (config: { source: Component; stub: Component }) => void
3132
}) => ConcreteComponent
3233

3334
interface StubOptions {
@@ -54,15 +55,15 @@ export const createStub = ({
5455
name,
5556
type,
5657
renderStubDefaultSlot
57-
}: StubOptions): DefineComponent => {
58+
}: StubOptions) => {
5859
const anonName = 'anonymous-stub'
5960
const tag = name ? `${hyphenate(name)}-stub` : anonName
6061

6162
const componentOptions = type
6263
? unwrapLegacyVueExtendComponent(type) || {}
6364
: {}
6465

65-
return defineComponent({
66+
const stub = defineComponent({
6667
name: name || anonName,
6768
props: (componentOptions as ConcreteComponent).props || {},
6869
// fix #1550 - respect old-style v-model for shallow mounted components with @vue/compat
@@ -84,6 +85,18 @@ export const createStub = ({
8485
}
8586
}
8687
})
88+
89+
const { __asyncLoader: asyncLoader } = type as ComponentOptions
90+
if (asyncLoader) {
91+
asyncLoader().then(() => {
92+
registerStub({
93+
source: (type as ComponentOptions).__asyncResolved,
94+
stub
95+
})
96+
})
97+
}
98+
99+
return stub
87100
}
88101

89102
const resolveComponentStubByName = (
@@ -230,7 +243,8 @@ export function createStubComponentsTransformer({
230243
return (
231244
config.plugins.createStubs?.({
232245
name: stubName,
233-
component: type
246+
component: type,
247+
registerStub
234248
}) ??
235249
createStub({
236250
name: stubName,

tests/features/async-components.spec.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'
22
import { defineAsyncComponent, defineComponent, h, AppConfig } from 'vue'
3-
import { mount, flushPromises } from '../../src'
3+
import { mount, shallowMount, flushPromises } from '../../src'
4+
import Hello from '../components/Hello.vue'
45

56
const config: Partial<AppConfig> = {
67
errorHandler: (error: unknown) => {
@@ -108,4 +109,38 @@ describe('defineAsyncComponent', () => {
108109
await vi.dynamicImportSettled()
109110
expect(wrapper.html()).toContain('Hello world')
110111
})
112+
113+
it('finds Async Component by async definition when using shallow mount', async () => {
114+
const AsyncHello = defineAsyncComponent(
115+
() => import('../components/Hello.vue')
116+
)
117+
118+
const Comp = defineComponent({
119+
render() {
120+
return h(AsyncHello)
121+
}
122+
})
123+
124+
const wrapper = shallowMount(Comp)
125+
await flushPromises()
126+
await vi.dynamicImportSettled()
127+
expect(wrapper.findComponent(AsyncHello).exists()).toBe(true)
128+
})
129+
130+
it('finds Async Component by definition when using shallow mount', async () => {
131+
const AsyncHello = defineAsyncComponent(
132+
() => import('../components/Hello.vue')
133+
)
134+
135+
const Comp = defineComponent({
136+
render() {
137+
return h(AsyncHello)
138+
}
139+
})
140+
141+
const wrapper = shallowMount(Comp)
142+
await flushPromises()
143+
await vi.dynamicImportSettled()
144+
expect(wrapper.findComponent(Hello).exists()).toBe(true)
145+
})
111146
})

tests/features/plugins.spec.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
vi
99
} from 'vitest'
1010
import { ComponentPublicInstance, h } from 'vue'
11-
1211
import { mount, config, VueWrapper } from '../../src'
1312

1413
declare module '../../src/vueWrapper' {
@@ -145,11 +144,13 @@ describe('createStubs', () => {
145144
expect(customCreateStub).toHaveBeenCalledTimes(2)
146145
expect(customCreateStub).toHaveBeenCalledWith({
147146
name: 'child1',
148-
component: Child1
147+
component: Child1,
148+
registerStub: expect.any(Function)
149149
})
150150
expect(customCreateStub).toHaveBeenCalledWith({
151151
name: 'child2',
152-
component: Child2
152+
component: Child2,
153+
registerStub: expect.any(Function)
153154
})
154155
})
155156

@@ -173,7 +174,8 @@ describe('createStubs', () => {
173174
expect(customCreateStub).toHaveBeenCalledTimes(1)
174175
expect(customCreateStub).toHaveBeenCalledWith({
175176
name: 'child2',
176-
component: Child2
177+
component: Child2,
178+
registerStub: expect.any(Function)
177179
})
178180
})
179181

@@ -212,7 +214,8 @@ describe('createStubs', () => {
212214
expect(customCreateStub).toHaveBeenCalledTimes(1)
213215
expect(customCreateStub).toHaveBeenCalledWith({
214216
name: 'child1',
215-
component: Child1
217+
component: Child1,
218+
registerStub: expect.any(Function)
216219
})
217220
})
218221
})

tests/mountingOptions/global.stubs.spec.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -679,16 +679,16 @@ describe('mounting options: stubs', () => {
679679
})
680680

681681
describe('stub async component', () => {
682-
const AsyncComponent = defineAsyncComponent(async () => ({
683-
name: 'AsyncComponent',
684-
template: '<span>AsyncComponent</span>'
685-
}))
686-
687682
const AsyncComponentWithoutName = defineAsyncComponent(async () => ({
688683
template: '<span>AsyncComponent</span>'
689684
}))
690685

691686
it('stubs async component with name', async () => {
687+
const AsyncComponent = defineAsyncComponent(async () => ({
688+
name: 'AsyncComponent',
689+
template: '<span>AsyncComponent</span>'
690+
}))
691+
692692
const TestComponent = defineComponent({
693693
components: {
694694
MyComponent: AsyncComponent
@@ -716,6 +716,11 @@ describe('mounting options: stubs', () => {
716716
})
717717

718718
it('stubs async component with name by alias', () => {
719+
const AsyncComponent = defineAsyncComponent(async () => ({
720+
name: 'AsyncComponent',
721+
template: '<span>AsyncComponent</span>'
722+
}))
723+
719724
const TestComponent = defineComponent({
720725
components: {
721726
MyComponent: AsyncComponent

0 commit comments

Comments
 (0)