Skip to content

Commit 6a4e19d

Browse files
authored
fix: support async components in stubs (#1039)
Fixes #1026
1 parent e1fd705 commit 6a4e19d

File tree

4 files changed

+52
-13
lines changed

4 files changed

+52
-13
lines changed

packages/shared/create-component-stubs.js renamed to packages/create-instance/create-component-stubs.js

+15-11
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ import {
66
camelize,
77
capitalize,
88
hyphenate
9-
} from './util'
9+
} from '../shared/util'
1010
import {
1111
componentNeedsCompiling,
1212
templateContainsComponent,
1313
isVueComponent
14-
} from './validators'
14+
} from '../shared/validators'
1515
import {
1616
compileTemplate,
1717
compileFromString
18-
} from './compile-template'
18+
} from '../shared/compile-template'
1919

2020
function isVueComponentStub (comp): boolean {
2121
return comp && comp.template || isVueComponent(comp)
@@ -68,10 +68,12 @@ export function createStubFromComponent (
6868
originalComponent: Component,
6969
name: string
7070
): Component {
71-
const componentOptions = typeof originalComponent === 'function'
72-
? originalComponent.extendOptions
73-
: originalComponent
74-
const tagName = `${name}-stub`
71+
const componentOptions =
72+
typeof originalComponent === 'function' && originalComponent.cid
73+
? originalComponent.extendOptions
74+
: originalComponent
75+
76+
const tagName = `${name || 'anonymous'}-stub`
7577

7678
// ignoreElements does not exist in Vue 2.0.x
7779
if (Vue.config.ignoredElements) {
@@ -112,9 +114,10 @@ export function createStubFromString (
112114
throwError('options.stub cannot contain a circular reference')
113115
}
114116

115-
const componentOptions = typeof originalComponent === 'function'
116-
? originalComponent.extendOptions
117-
: originalComponent
117+
const componentOptions =
118+
typeof originalComponent === 'function' && originalComponent.cid
119+
? originalComponent.extendOptions
120+
: originalComponent
118121

119122
return {
120123
...getCoreProperties(componentOptions),
@@ -152,9 +155,10 @@ export function createStubsFromStubsObject (
152155
}
153156

154157
if (typeof stub === 'string') {
158+
const component = resolveComponent(originalComponents, stubName)
155159
acc[stubName] = createStubFromString(
156160
stub,
157-
originalComponents[stubName],
161+
component,
158162
stubName
159163
)
160164
return acc

packages/create-instance/create-instance.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import createFunctionalComponent from './create-functional-component'
1414
import { componentNeedsCompiling, isPlainObject } from 'shared/validators'
1515
import { validateSlots } from './validate-slots'
1616
import createScopedSlots from './create-scoped-slots'
17-
import { createStubsFromStubsObject } from 'shared/create-component-stubs'
17+
import { createStubsFromStubsObject } from './create-component-stubs'
1818
import { patchRender } from './patch-render'
1919

2020
function vueExtendUnsupportedOption (option: string) {

packages/create-instance/patch-render.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createStubFromComponent } from 'shared/create-component-stubs'
1+
import { createStubFromComponent } from './create-component-stubs'
22
import { resolveComponent, semVerGreaterThan } from 'shared/util'
33
import { isReservedTag } from 'shared/validators'
44
import { addHook } from './add-hook'

test/specs/mounting-options/stubs.spec.js

+35
Original file line numberDiff line numberDiff line change
@@ -532,4 +532,39 @@ describeWithMountingMethods('options.stub', mountingMethod => {
532532
expect(fn).to.throw()
533533
.with.property('message', message)
534534
})
535+
536+
it('works with async components', () => {
537+
const StubComponent = {
538+
template: '<h1 />'
539+
}
540+
const TestComponent = {
541+
template: `<div>
542+
<dynamic-hello />
543+
<dynamic-hello-2 />
544+
<dynamic-hello-3 />
545+
</div>`,
546+
components: {
547+
DynamicHello: () => import('~resources/components/component.vue'),
548+
DynamicHello2: () => import('~resources/components/component.vue'),
549+
DynamicHello3: () => import('~resources/components/component.vue')
550+
}
551+
}
552+
const wrapper = mountingMethod(TestComponent, {
553+
stubs: {
554+
DynamicHello: '<span />',
555+
DynamicHello2: true,
556+
DynamicHello3: StubComponent
557+
}
558+
})
559+
const HTML =
560+
mountingMethod.name === 'renderToString' ? wrapper : wrapper.html()
561+
562+
expect(HTML).to.contain('span')
563+
expect(HTML).to.contain(
564+
mountingMethod.name === 'renderToString'
565+
? 'DynamicHello2-stub'
566+
: 'dynamichello2-stub'
567+
)
568+
expect(HTML).to.contain('h1')
569+
})
535570
})

0 commit comments

Comments
 (0)