@@ -85,8 +85,8 @@ export const createFor = (
85
85
const parentAnchor = __DEV__ ? createComment ( 'for' ) : createTextNode ( )
86
86
const frag = new VaporFragment ( oldBlocks )
87
87
const instance = currentInstance !
88
- const canUseFastRemove = flags & VaporVForFlags . FAST_REMOVE
89
- const isComponent = flags & VaporVForFlags . IS_COMPONENT
88
+ const canUseFastRemove = ! ! ( flags & VaporVForFlags . FAST_REMOVE )
89
+ const isComponent = ! ! ( flags & VaporVForFlags . IS_COMPONENT )
90
90
const selectors : {
91
91
deregister : ( key : any ) => void
92
92
cleanup : ( ) => void
@@ -196,28 +196,88 @@ export const createFor = (
196
196
pendingNews . push ( [ i , item , key ] )
197
197
}
198
198
199
+ let pendingMountsLength = 0
200
+
201
+ const pendingMounts : [
202
+ index : number ,
203
+ item : ReturnType < typeof getItem > ,
204
+ key : any ,
205
+ anchorIndex : number ,
206
+ ] [ ] = new Array ( newLength )
207
+ const moveOrMount = (
208
+ index : number ,
209
+ item : ReturnType < typeof getItem > ,
210
+ key : any ,
211
+ anchorIndex : number ,
212
+ ) => {
213
+ const oldIndex = oldKeyToIndexMap . get ( key )
214
+ if ( oldIndex !== undefined ) {
215
+ const block = ( newBlocks [ index ] = oldBlocks [ oldIndex ] )
216
+ update ( block , ...item )
217
+ insert (
218
+ block ,
219
+ parent ! ,
220
+ anchorIndex === - 1
221
+ ? defaultAnchor
222
+ : normalizeAnchor ( newBlocks [ anchorIndex ] . nodes ) ,
223
+ )
224
+ oldKeyToIndexMap . delete ( key )
225
+ } else {
226
+ pendingMounts [ pendingMountsLength ++ ] = [
227
+ index ,
228
+ item ,
229
+ key ,
230
+ anchorIndex ,
231
+ ]
232
+ }
233
+ }
234
+
199
235
for ( let i = pendingNews . length - 1 ; i >= 0 ; i -- ) {
200
236
const [ index , item , key ] = pendingNews [ i ]
201
237
moveOrMount (
202
- oldKeyToIndexMap ,
203
- source ,
204
238
index ,
205
239
item ,
206
240
key ,
207
- index < prepareLength - 1
208
- ? normalizeAnchor ( newBlocks [ index + 1 ] . nodes )
209
- : defaultAnchor ,
241
+ index < prepareLength - 1 ? index + 1 : - 1 ,
210
242
)
211
243
}
212
244
213
245
for ( let i = prepareLength ; i < newLength - right ; i ++ ) {
214
246
const item = getItem ( source , i )
215
247
const key = getKey . apply ( null , item )
216
- moveOrMount ( oldKeyToIndexMap , source , i , item , key , defaultAnchor )
248
+ moveOrMount ( i , item , key , - 1 )
217
249
}
218
250
251
+ const shouldUseFastRemove = pendingMountsLength === newLength
252
+
219
253
for ( const i of oldKeyToIndexMap . values ( ) ) {
220
- unmount ( oldBlocks [ i ] )
254
+ unmount (
255
+ oldBlocks [ i ] ,
256
+ ! ( shouldUseFastRemove && canUseFastRemove ) ,
257
+ ! shouldUseFastRemove ,
258
+ )
259
+ }
260
+ if ( shouldUseFastRemove ) {
261
+ for ( const selector of selectors ) {
262
+ selector . cleanup ( )
263
+ }
264
+ }
265
+ if ( shouldUseFastRemove && canUseFastRemove ) {
266
+ parent ! . textContent = ''
267
+ parent ! . appendChild ( parentAnchor )
268
+ }
269
+
270
+ for ( let i = 0 ; i < pendingMountsLength ; i ++ ) {
271
+ const [ index , item , key , anchorIndex ] = pendingMounts [ i ]
272
+ mount (
273
+ source ,
274
+ index ,
275
+ item ,
276
+ key ,
277
+ anchorIndex === - 1
278
+ ? defaultAnchor
279
+ : normalizeAnchor ( newBlocks [ anchorIndex ] . nodes ) ,
280
+ )
221
281
}
222
282
}
223
283
}
@@ -272,25 +332,6 @@ export const createFor = (
272
332
return block
273
333
}
274
334
275
- const moveOrMount = (
276
- keyToOldIndexMap : Map < any , number > ,
277
- source : ResolvedSource ,
278
- index : number ,
279
- item : ReturnType < typeof getItem > ,
280
- key : any ,
281
- anchor : Node ,
282
- ) => {
283
- const oldIndex = keyToOldIndexMap . get ( key )
284
- if ( oldIndex !== undefined ) {
285
- const block = ( newBlocks [ index ] = oldBlocks [ oldIndex ] )
286
- update ( block , ...item )
287
- insert ( block , parent ! , anchor )
288
- keyToOldIndexMap . delete ( key )
289
- } else {
290
- mount ( source , index , item , key , anchor )
291
- }
292
- }
293
-
294
335
const update = (
295
336
{ itemRef, keyRef, indexRef } : ForBlock ,
296
337
newItem : any ,
@@ -308,16 +349,16 @@ export const createFor = (
308
349
}
309
350
}
310
351
311
- const unmount = (
312
- { nodes , scope , key } : ForBlock ,
313
- doRemove = true ,
314
- doDeregister = true ,
315
- ) => {
316
- scope && scope . stop ( )
317
- doRemove && removeBlock ( nodes , parent ! )
352
+ const unmount = ( block : ForBlock , doRemove = true , doDeregister = true ) => {
353
+ if ( ! isComponent ) {
354
+ block . scope ! . stop ( )
355
+ }
356
+ if ( doRemove ) {
357
+ removeBlock ( block . nodes , parent ! )
358
+ }
318
359
if ( doDeregister ) {
319
360
for ( const selector of selectors ) {
320
- selector . deregister ( key )
361
+ selector . deregister ( block . key )
321
362
}
322
363
}
323
364
}
0 commit comments