Skip to content

Commit ec99da1

Browse files
committed
fix: add support for proper props update in async mode
Since we're already wrapping a component into a parent one we can get rid of explicitly setting props on component, instead modifying them being passed from parent component instead
1 parent a313af2 commit ec99da1

File tree

2 files changed

+18
-29
lines changed

2 files changed

+18
-29
lines changed

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

+9-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import createScopedSlots from './create-scoped-slots'
1111
import { createStubsFromStubsObject } from './create-component-stubs'
1212
import { patchCreateElement } from './patch-create-element'
1313

14-
function createContext(options, scopedSlots) {
14+
function createContext(options, scopedSlots, currentProps) {
1515
const on = {
1616
...(options.context && options.context.on),
1717
...options.listeners
@@ -21,7 +21,7 @@ function createContext(options, scopedSlots) {
2121
...options.attrs,
2222
// pass as attrs so that inheritAttrs works correctly
2323
// propsData should take precedence over attrs
24-
...options.propsData
24+
...currentProps
2525
},
2626
...(options.context || {}),
2727
on,
@@ -84,10 +84,16 @@ export default function createInstance(
8484
parentComponentOptions.provide = options.provide
8585
parentComponentOptions.$_doNotStubChildren = true
8686
parentComponentOptions._isFunctionalContainer = componentOptions.functional
87+
const originalDataFn = parentComponentOptions.data
88+
parentComponentOptions.data = function() {
89+
const originalData = originalDataFn ? originalDataFn() : {}
90+
originalData.vueTestUtils_childProps = { ...options.propsData }
91+
return originalData
92+
}
8793
parentComponentOptions.render = function(h) {
8894
return h(
8995
Constructor,
90-
createContext(options, scopedSlots),
96+
createContext(options, scopedSlots, this.vueTestUtils_childProps),
9197
createChildren(this, h, options)
9298
)
9399
}

Diff for: packages/test-utils/src/wrapper.js

+9-26
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
// @flow
2-
3-
import Vue from 'vue'
42
import pretty from 'pretty'
53
import getSelector from './get-selector'
64
import { REF_SELECTOR, FUNCTIONAL_OPTIONS, VUE_VERSION } from 'shared/consts'
7-
import config from './config'
85
import WrapperArray from './wrapper-array'
96
import ErrorWrapper from './error-wrapper'
107
import { throwError, getCheckedEvent, isPhantomJS } from 'shared/util'
@@ -455,8 +452,6 @@ export default class Wrapper implements BaseWrapper {
455452
* Sets vm props
456453
*/
457454
setProps(data: Object): void {
458-
const originalConfig = Vue.config.silent
459-
Vue.config.silent = config.silent
460455
if (this.isFunctionalComponent) {
461456
throwError(
462457
`wrapper.setProps() cannot be called on a functional component`
@@ -480,38 +475,26 @@ export default class Wrapper implements BaseWrapper {
480475
)
481476
}
482477
if (
483-
!this.vm ||
484-
!this.vm.$options._propKeys ||
485-
!this.vm.$options._propKeys.some(prop => prop === key)
478+
VUE_VERSION <= 2.3 &&
479+
// $FlowIgnore : Problem with possibly null this.vm
480+
(!this.vm.$options._propKeys ||
481+
!this.vm.$options._propKeys.some(prop => prop === key))
486482
) {
487-
if (VUE_VERSION > 2.3) {
488-
// $FlowIgnore : Problem with possibly null this.vm
489-
this.vm.$attrs[key] = data[key]
490-
return
491-
}
492483
throwError(
493484
`wrapper.setProps() called with ${key} property which ` +
494485
`is not defined on the component`
495486
)
496487
}
497488

498-
if (this.vm && this.vm._props) {
499-
// Set actual props value
500-
this.vm._props[key] = data[key]
501-
// $FlowIgnore : Problem with possibly null this.vm
502-
this.vm[key] = data[key]
503-
} else {
504-
// $FlowIgnore : Problem with possibly null this.vm.$options
505-
this.vm.$options.propsData[key] = data[key]
506-
// $FlowIgnore : Problem with possibly null this.vm
507-
this.vm[key] = data[key]
508-
// $FlowIgnore : Need to call this twice to fix watcher bug in 2.0.x
509-
this.vm[key] = data[key]
489+
if (this.vm && this.vm.$parent) {
490+
this.vm.$parent.vueTestUtils_childProps[key] = data[key]
510491
}
511492
})
512493
// $FlowIgnore : Problem with possibly null this.vm
513494
this.vm.$forceUpdate()
514-
Vue.config.silent = originalConfig
495+
// We need to explicitly trigger parent watcher to support sync scenarios
496+
// $FlowIgnore : Problem with possibly null this.vm
497+
this.vm.$parent._watcher.run()
515498
}
516499

517500
/**

0 commit comments

Comments
 (0)