@@ -478,63 +478,67 @@ export default class Wrapper implements BaseWrapper {
478478 * Sets vm props
479479 */
480480 setProps ( data : Object ) : void {
481- const originalConfig = Vue . config . silent
482- Vue . config . silent = config . silent
481+ // Validate the setProps method call
483482 if ( this . isFunctionalComponent ) {
484483 throwError (
485484 `wrapper.setProps() cannot be called on a functional component`
486485 )
487486 }
487+
488488 if ( ! this . vm ) {
489489 throwError ( `wrapper.setProps() can only be called on a Vue instance` )
490490 }
491491
492- Object . keys ( data ) . forEach ( key => {
493- if (
494- typeof data [ key ] === 'object' &&
495- data [ key ] !== null &&
496- // $FlowIgnore : Problem with possibly null this.vm
497- data [ key ] === this . vm [ key ]
498- ) {
499- throwError (
500- `wrapper.setProps() called with the same object of the existing ` +
501- `${ key } property. You must call wrapper.setProps() with a new ` +
502- `object to trigger reactivity`
503- )
504- }
505- if (
506- ! this . vm ||
507- ! this . vm . $options . _propKeys ||
508- ! this . vm . $options . _propKeys . some ( prop => prop === key )
509- ) {
510- if ( VUE_VERSION > 2.3 ) {
492+ // Save the original "silent" config so that we can directly mutate props
493+ const originalConfig = Vue . config . silent
494+ Vue . config . silent = config . silent
495+
496+ try {
497+ Object . keys ( data ) . forEach ( key => {
498+ // Don't let people set entire objects, because reactivity won't work
499+ if (
500+ typeof data [ key ] === 'object' &&
501+ data [ key ] !== null &&
511502 // $FlowIgnore : Problem with possibly null this.vm
512- this . vm . $attrs [ key ] = data [ key ]
513- return
503+ data [ key ] === this . vm [ key ]
504+ ) {
505+ throwError (
506+ `wrapper.setProps() called with the same object of the existing ` +
507+ `${ key } property. You must call wrapper.setProps() with a new ` +
508+ `object to trigger reactivity`
509+ )
514510 }
515- throwError (
516- `wrapper.setProps() called with ${ key } property which ` +
517- `is not defined on the component`
518- )
519- }
520511
521- if ( this . vm && this . vm . _props ) {
522- // Set actual props value
523- this . vm . _props [ key ] = data [ key ]
524- // $FlowIgnore : Problem with possibly null this.vm
525- this . vm [ key ] = data [ key ]
526- } else {
527- // $FlowIgnore : Problem with possibly null this.vm.$options
528- this . vm . $options . propsData [ key ] = data [ key ]
512+ if (
513+ ! this . vm ||
514+ ! this . vm . $options . _propKeys ||
515+ ! this . vm . $options . _propKeys . some ( prop => prop === key )
516+ ) {
517+ if ( VUE_VERSION > 2.3 ) {
518+ // $FlowIgnore : Problem with possibly null this.vm
519+ this . vm . $attrs [ key ] = data [ key ]
520+ return
521+ }
522+ throwError (
523+ `wrapper.setProps() called with ${ key } property which ` +
524+ `is not defined on the component`
525+ )
526+ }
527+
528+ // Actually set the prop
529529 // $FlowIgnore : Problem with possibly null this.vm
530530 this . vm [ key ] = data [ key ]
531- // $FlowIgnore : Need to call this twice to fix watcher bug in 2.0.x
532- this . vm [ key ] = data [ key ]
533- }
534- } )
535- // $FlowIgnore : Problem with possibly null this.vm
536- this . vm . $forceUpdate ( )
537- Vue . config . silent = originalConfig
531+ } )
532+
533+ // $FlowIgnore : Problem with possibly null this.vm
534+ this . vm . $forceUpdate ( )
535+ } catch ( err ) {
536+ throw err
537+ } finally {
538+ // Ensure you teardown the modifications you made to the user's config
539+ // After all the props are set, then reset the state
540+ Vue . config . silent = originalConfig
541+ }
538542 }
539543
540544 /**
0 commit comments