@@ -478,63 +478,67 @@ export default class Wrapper implements BaseWrapper {
478
478
* Sets vm props
479
479
*/
480
480
setProps ( data : Object ) : void {
481
- const originalConfig = Vue . config . silent
482
- Vue . config . silent = config . silent
481
+ // Validate the setProps method call
483
482
if ( this . isFunctionalComponent ) {
484
483
throwError (
485
484
`wrapper.setProps() cannot be called on a functional component`
486
485
)
487
486
}
487
+
488
488
if ( ! this . vm ) {
489
489
throwError ( `wrapper.setProps() can only be called on a Vue instance` )
490
490
}
491
491
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 &&
511
502
// $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
+ )
514
510
}
515
- throwError (
516
- `wrapper.setProps() called with ${ key } property which ` +
517
- `is not defined on the component`
518
- )
519
- }
520
511
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
529
529
// $FlowIgnore : Problem with possibly null this.vm
530
530
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
+ }
538
542
}
539
543
540
544
/**
0 commit comments