File tree 3 files changed +67
-2
lines changed
test/unit/modules/vdom/patch
3 files changed +67
-2
lines changed Original file line number Diff line number Diff line change @@ -116,6 +116,10 @@ export function lifecycleMixin (Vue: Class<Component>) {
116
116
const vm : Component = this
117
117
const hasChildren = ! ! ( vm . $options . _renderChildren || renderChildren )
118
118
vm . $options . _parentVnode = parentVnode
119
+ vm . $vnode = parentVnode // update vm's placeholder node without re-render
120
+ if ( vm . _vnode ) { // update child tree's parent
121
+ vm . _vnode . parent = parentVnode
122
+ }
119
123
vm . $options . _renderChildren = renderChildren
120
124
// update props
121
125
if ( propsData && vm . $options . props ) {
Original file line number Diff line number Diff line change @@ -505,9 +505,13 @@ export function createPatchFunction (backend) {
505
505
createElm ( vnode , insertedVnodeQueue )
506
506
507
507
// component root element replaced.
508
- // update parent placeholder node element.
508
+ // update parent placeholder node element, recursively
509
509
if ( vnode . parent ) {
510
- vnode . parent . elm = vnode . elm
510
+ let ancestor = vnode . parent
511
+ while ( ancestor ) {
512
+ ancestor . elm = vnode . elm
513
+ ancestor = ancestor . parent
514
+ }
511
515
if ( isPatchable ( vnode ) ) {
512
516
for ( let i = 0 ; i < cbs . create . length ; ++ i ) {
513
517
cbs . create [ i ] ( emptyNode , vnode . parent )
Original file line number Diff line number Diff line change @@ -57,4 +57,61 @@ describe('vdom patch: edge cases', () => {
57
57
expect ( vm . $el . querySelector ( '.d' ) . textContent ) . toBe ( '2' )
58
58
} ) . then ( done )
59
59
} )
60
+
61
+ it ( 'should synchronize vm\' vnode' , done => {
62
+ const comp = {
63
+ data : ( ) => ( { swap : true } ) ,
64
+ render ( h ) {
65
+ return this . swap
66
+ ? h ( 'a' , 'atag' )
67
+ : h ( 'span' , 'span' )
68
+ }
69
+ }
70
+
71
+ const wrapper = {
72
+ render : h => h ( 'comp' ) ,
73
+ components : { comp }
74
+ }
75
+
76
+ const vm = new Vue ( {
77
+ render ( h ) {
78
+ const children = [
79
+ h ( 'wrapper' ) ,
80
+ h ( 'div' , 'row' )
81
+ ]
82
+ if ( this . swap ) {
83
+ children . reverse ( )
84
+ }
85
+ return h ( 'div' , children )
86
+ } ,
87
+ data : ( ) => ( { swap : false } ) ,
88
+ components : { wrapper }
89
+ } ) . $mount ( )
90
+
91
+ expect ( vm . $el . innerHTML ) . toBe ( '<a>atag</a><div>row</div>' )
92
+ const wrapperVm = vm . $children [ 0 ]
93
+ const compVm = wrapperVm . $children [ 0 ]
94
+ vm . swap = true
95
+ waitForUpdate ( ( ) => {
96
+ expect ( compVm . $vnode . parent ) . toBe ( wrapperVm . $vnode )
97
+ expect ( vm . $el . innerHTML ) . toBe ( '<div>row</div><a>atag</a>' )
98
+ vm . swap = false
99
+ } )
100
+ . then ( ( ) => {
101
+ expect ( compVm . $vnode . parent ) . toBe ( wrapperVm . $vnode )
102
+ expect ( vm . $el . innerHTML ) . toBe ( '<a>atag</a><div>row</div>' )
103
+ compVm . swap = false
104
+ } )
105
+ . then ( ( ) => {
106
+ expect ( vm . $el . innerHTML ) . toBe ( '<span>span</span><div>row</div>' )
107
+ expect ( compVm . $vnode . parent ) . toBe ( wrapperVm . $vnode )
108
+ vm . swap = true
109
+ } )
110
+ . then ( ( ) => {
111
+ expect ( vm . $el . innerHTML ) . toBe ( '<div>row</div><span>span</span>' )
112
+ expect ( compVm . $vnode . parent ) . toBe ( wrapperVm . $vnode )
113
+ vm . swap = true
114
+ } )
115
+ . then ( done )
116
+ } )
60
117
} )
You can’t perform that action at this time.
0 commit comments