10
10
* of making flow understand it is not worth it.
11
11
*/
12
12
13
- import VNode from './vnode'
13
+ import VNode , { cloneVNode } from './vnode'
14
14
import config from '../config'
15
15
import { SSR_ATTR } from 'shared/constants'
16
16
import { registerRef } from './modules/ref'
@@ -121,7 +121,25 @@ export function createPatchFunction (backend) {
121
121
}
122
122
123
123
let creatingElmInVPre = 0
124
- function createElm ( vnode , insertedVnodeQueue , parentElm , refElm , nested ) {
124
+
125
+ function createElm (
126
+ vnode ,
127
+ insertedVnodeQueue ,
128
+ parentElm ,
129
+ refElm ,
130
+ nested ,
131
+ ownerArray ,
132
+ index
133
+ ) {
134
+ if ( isDef ( vnode . elm ) && isDef ( ownerArray ) ) {
135
+ // This vnode was used in a previous render!
136
+ // now it's used as a new node, overwriting its elm would cause
137
+ // potential patch errors down the road when it's used as an insertion
138
+ // reference node. Instead, we clone the node on-demand before creating
139
+ // associated DOM element for it.
140
+ vnode = ownerArray [ index ] = cloneVNode ( vnode )
141
+ }
142
+
125
143
vnode . isRootInsert = ! nested // for transition enter check
126
144
if ( createComponent ( vnode , insertedVnodeQueue , parentElm , refElm ) ) {
127
145
return
@@ -144,6 +162,7 @@ export function createPatchFunction (backend) {
144
162
)
145
163
}
146
164
}
165
+
147
166
vnode . elm = vnode . ns
148
167
? nodeOps . createElementNS ( vnode . ns , tag )
149
168
: nodeOps . createElement ( tag , vnode )
@@ -267,7 +286,7 @@ export function createPatchFunction (backend) {
267
286
checkDuplicateKeys ( children )
268
287
}
269
288
for ( let i = 0 ; i < children . length ; ++ i ) {
270
- createElm ( children [ i ] , insertedVnodeQueue , vnode . elm , null , true )
289
+ createElm ( children [ i ] , insertedVnodeQueue , vnode . elm , null , true , children , i )
271
290
}
272
291
} else if ( isPrimitive ( vnode . text ) ) {
273
292
nodeOps . appendChild ( vnode . elm , nodeOps . createTextNode ( String ( vnode . text ) ) )
@@ -320,7 +339,7 @@ export function createPatchFunction (backend) {
320
339
321
340
function addVnodes ( parentElm , refElm , vnodes , startIdx , endIdx , insertedVnodeQueue ) {
322
341
for ( ; startIdx <= endIdx ; ++ startIdx ) {
323
- createElm ( vnodes [ startIdx ] , insertedVnodeQueue , parentElm , refElm )
342
+ createElm ( vnodes [ startIdx ] , insertedVnodeQueue , parentElm , refElm , false , vnodes , startIdx )
324
343
}
325
344
}
326
345
@@ -430,7 +449,7 @@ export function createPatchFunction (backend) {
430
449
? oldKeyToIdx [ newStartVnode . key ]
431
450
: findIdxInOld ( newStartVnode , oldCh , oldStartIdx , oldEndIdx )
432
451
if ( isUndef ( idxInOld ) ) { // New element
433
- createElm ( newStartVnode , insertedVnodeQueue , parentElm , oldStartVnode . elm )
452
+ createElm ( newStartVnode , insertedVnodeQueue , parentElm , oldStartVnode . elm , false , newCh , newStartIdx )
434
453
} else {
435
454
vnodeToMove = oldCh [ idxInOld ]
436
455
if ( sameVnode ( vnodeToMove , newStartVnode ) ) {
@@ -439,7 +458,7 @@ export function createPatchFunction (backend) {
439
458
canMove && nodeOps . insertBefore ( parentElm , vnodeToMove . elm , oldStartVnode . elm )
440
459
} else {
441
460
// same key but different element. treat as new element
442
- createElm ( newStartVnode , insertedVnodeQueue , parentElm , oldStartVnode . elm )
461
+ createElm ( newStartVnode , insertedVnodeQueue , parentElm , oldStartVnode . elm , false , newCh , newStartIdx )
443
462
}
444
463
}
445
464
newStartVnode = newCh [ ++ newStartIdx ]
0 commit comments