@@ -218,7 +218,7 @@ export function createPatchFunction (backend) {
218218 }
219219 }
220220
221- function updateChildren ( parentElm , oldCh , newCh , insertedVnodeQueue ) {
221+ function updateChildren ( parentElm , oldCh , newCh , insertedVnodeQueue , removeOnly ) {
222222 let oldStartIdx = 0
223223 let newStartIdx = 0
224224 let oldEndIdx = oldCh . length - 1
@@ -229,6 +229,11 @@ export function createPatchFunction (backend) {
229229 let newEndVnode = newCh [ newEndIdx ]
230230 let oldKeyToIdx , idxInOld , elmToMove , before
231231
232+ // removeOnly is a special flag used only by <transition-group>
233+ // to ensure removed elements stay in correct relative positions
234+ // during leaving transitions
235+ const canMove = ! removeOnly
236+
232237 while ( oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx ) {
233238 if ( isUndef ( oldStartVnode ) ) {
234239 oldStartVnode = oldCh [ ++ oldStartIdx ] // Vnode has been moved left
@@ -244,12 +249,12 @@ export function createPatchFunction (backend) {
244249 newEndVnode = newCh [ -- newEndIdx ]
245250 } else if ( sameVnode ( oldStartVnode , newEndVnode ) ) { // Vnode moved right
246251 patchVnode ( oldStartVnode , newEndVnode , insertedVnodeQueue )
247- nodeOps . insertBefore ( parentElm , oldStartVnode . elm , nodeOps . nextSibling ( oldEndVnode . elm ) )
252+ canMove && nodeOps . insertBefore ( parentElm , oldStartVnode . elm , nodeOps . nextSibling ( oldEndVnode . elm ) )
248253 oldStartVnode = oldCh [ ++ oldStartIdx ]
249254 newEndVnode = newCh [ -- newEndIdx ]
250255 } else if ( sameVnode ( oldEndVnode , newStartVnode ) ) { // Vnode moved left
251256 patchVnode ( oldEndVnode , newStartVnode , insertedVnodeQueue )
252- nodeOps . insertBefore ( parentElm , oldEndVnode . elm , oldStartVnode . elm )
257+ canMove && nodeOps . insertBefore ( parentElm , oldEndVnode . elm , oldStartVnode . elm )
253258 oldEndVnode = oldCh [ -- oldEndIdx ]
254259 newStartVnode = newCh [ ++ newStartIdx ]
255260 } else {
@@ -274,7 +279,7 @@ export function createPatchFunction (backend) {
274279 } else {
275280 patchVnode ( elmToMove , newStartVnode , insertedVnodeQueue )
276281 oldCh [ idxInOld ] = undefined
277- nodeOps . insertBefore ( parentElm , newStartVnode . elm , oldStartVnode . elm )
282+ canMove && nodeOps . insertBefore ( parentElm , newStartVnode . elm , oldStartVnode . elm )
278283 newStartVnode = newCh [ ++ newStartIdx ]
279284 }
280285 }
@@ -288,7 +293,7 @@ export function createPatchFunction (backend) {
288293 }
289294 }
290295
291- function patchVnode ( oldVnode , vnode , insertedVnodeQueue ) {
296+ function patchVnode ( oldVnode , vnode , insertedVnodeQueue , removeOnly ) {
292297 if ( oldVnode === vnode ) return
293298 let i , hook
294299 const hasData = isDef ( i = vnode . data )
@@ -304,7 +309,7 @@ export function createPatchFunction (backend) {
304309 }
305310 if ( isUndef ( vnode . text ) ) {
306311 if ( isDef ( oldCh ) && isDef ( ch ) ) {
307- if ( oldCh !== ch ) updateChildren ( elm , oldCh , ch , insertedVnodeQueue )
312+ if ( oldCh !== ch ) updateChildren ( elm , oldCh , ch , insertedVnodeQueue , removeOnly )
308313 } else if ( isDef ( ch ) ) {
309314 if ( isDef ( oldVnode . text ) ) nodeOps . setTextContent ( elm , '' )
310315 addVnodes ( elm , null , ch , 0 , ch . length - 1 , insertedVnodeQueue )
@@ -384,7 +389,7 @@ export function createPatchFunction (backend) {
384389 }
385390 }
386391
387- return function patch ( oldVnode , vnode , hydrating ) {
392+ return function patch ( oldVnode , vnode , hydrating , removeOnly ) {
388393 let elm , parent
389394 let isInitialPatch = false
390395 const insertedVnodeQueue = [ ]
@@ -396,7 +401,7 @@ export function createPatchFunction (backend) {
396401 } else {
397402 const isRealElement = isDef ( oldVnode . nodeType )
398403 if ( ! isRealElement && sameVnode ( oldVnode , vnode ) ) {
399- patchVnode ( oldVnode , vnode , insertedVnodeQueue )
404+ patchVnode ( oldVnode , vnode , insertedVnodeQueue , removeOnly )
400405 } else {
401406 if ( isRealElement ) {
402407 // mounting to a real element
0 commit comments