Skip to content

Commit 3653c60

Browse files
authored
feat: support lazily added components (#1005)
1 parent 1576284 commit 3653c60

File tree

7 files changed

+42
-7
lines changed

7 files changed

+42
-7
lines changed

Diff for: flow/options.flow.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ declare type Options = {
1414
listeners?: { [key: string]: Function | Array<Function> },
1515
parentComponent?: Object,
1616
logModifiedComponents?: boolean,
17-
sync?: boolean
17+
sync?: boolean,
18+
shouldProxy?: boolean
1819
};
1920

2021
declare type SlotValue = Component | string | Array<Component | string>;

Diff for: packages/create-instance/add-stubs.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { createStubsFromStubsObject } from 'shared/create-component-stubs'
1+
import {
2+
createStubsFromStubsObject,
3+
createStubFromComponent
4+
} from 'shared/create-component-stubs'
25
import { addHook } from './add-hook'
36

4-
export function addStubs (component, stubs, _Vue) {
7+
export function addStubs (component, stubs, _Vue, shouldProxy) {
58
const stubComponents = createStubsFromStubsObject(
69
component.components,
710
stubs
@@ -12,6 +15,16 @@ export function addStubs (component, stubs, _Vue) {
1215
this.$options.components,
1316
stubComponents
1417
)
18+
if (typeof Proxy !== 'undefined' && shouldProxy) {
19+
this.$options.components = new Proxy(this.$options.components, {
20+
set (target, prop, value) {
21+
if (!target[prop]) {
22+
target[prop] = createStubFromComponent(value, prop)
23+
}
24+
return true
25+
}
26+
})
27+
}
1528
}
1629

1730
addHook(_Vue.options, 'beforeMount', addStubComponentsMixin)

Diff for: packages/create-instance/create-instance.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export default function createInstance (
5959

6060
addEventLogger(_Vue)
6161
addMocks(options.mocks, _Vue)
62-
addStubs(component, options.stubs, _Vue)
62+
addStubs(component, options.stubs, _Vue, options.shouldProxy)
6363

6464
if (
6565
(component.options && component.options.functional) ||

Diff for: packages/create-instance/extract-instance-options.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ const MOUNTING_OPTIONS = [
1212
'listeners',
1313
'propsData',
1414
'logModifiedComponents',
15-
'sync'
15+
'sync',
16+
'shouldProxy'
1617
]
1718

1819
export default function extractInstanceOptions (

Diff for: packages/shared/create-component-stubs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export function createStubFromComponent (
102102
}
103103
}
104104

105-
function createStubFromString (
105+
export function createStubFromString (
106106
templateString: string,
107107
originalComponent: Component = {},
108108
name: string

Diff for: packages/test-utils/src/shallow-mount.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export default function shallowMount (
3131

3232
return mount(component, {
3333
...options,
34+
shouldProxy: true,
3435
components: {
3536
...createStubsForComponent(_Vue),
3637
...createStubsForComponent(component)

Diff for: test/specs/shallow-mount.spec.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import ComponentWithoutName from '~resources/components/component-without-name.v
99
import ComponentAsAClassWithChild from '~resources/components/component-as-a-class-with-child.vue'
1010
import RecursiveComponent from '~resources/components/recursive-component.vue'
1111
import { vueVersion } from '~resources/utils'
12-
import { describeRunIf, itDoNotRunIf } from 'conditional-specs'
12+
import { describeRunIf, itDoNotRunIf, itSkipIf } from 'conditional-specs'
1313

1414
describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => {
1515
beforeEach(() => {
@@ -389,6 +389,25 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => {
389389
.to.equal('hey')
390390
})
391391

392+
itSkipIf(
393+
typeof Proxy === 'undefined',
394+
'stubs lazily registered components', () => {
395+
const Child = {
396+
render: h => h('p')
397+
}
398+
const TestComponent = {
399+
template: '<div><child /></div>',
400+
beforeCreate () {
401+
this.$options.components.Child = Child
402+
}
403+
}
404+
const wrapper = shallowMount(TestComponent)
405+
406+
expect(wrapper.findAll('p').length)
407+
.to.equal(0)
408+
expect(wrapper.findAll(Child).length).to.equal(1)
409+
})
410+
392411
itDoNotRunIf(
393412
vueVersion < 2.4, // auto resolve of default export added in 2.4
394413
'handles component as dynamic import', () => {

0 commit comments

Comments
 (0)