Skip to content

Commit c9ccc34

Browse files
committed
chore: fix cherrypick of rewrite
1 parent 14faf2a commit c9ccc34

File tree

1 file changed

+23
-94
lines changed

1 file changed

+23
-94
lines changed

packages/vue-virtual-scroller/src/components/RecycleScroller.vue

+23-94
Original file line numberDiff line numberDiff line change
@@ -241,15 +241,6 @@ export default {
241241
},
242242
243243
simpleArray,
244-
245-
itemIndexByKey () {
246-
const { keyField, items } = this
247-
const result = {}
248-
for (let i = 0, l = items.length; i < l; i++) {
249-
result[items[i][keyField]] = i
250-
}
251-
return result
252-
},
253244
},
254245
255246
watch: {
@@ -438,7 +429,6 @@ export default {
438429
const sizes = this.sizes
439430
const views = this.$_views
440431
const pool = this.pool
441-
const itemIndexByKey = this.itemIndexByKey
442432
let startIndex, endIndex
443433
let totalSize
444434
let visibleStartIndex, visibleEndIndex
@@ -550,43 +540,24 @@ export default {
550540
551541
const continuous = startIndex <= this.$_endIndex && endIndex >= this.$_startIndex
552542
553-
if (this.$_continuous !== continuous) {
554-
if (continuous) {
555-
views.clear()
556-
unusedViews.clear()
557-
for (let i = 0, l = pool.length; i < l; i++) {
558-
view = pool[i]
559-
this.unuseView(view)
560-
}
561-
}
562-
this.$_continuous = continuous
563-
} else if (continuous) {
543+
// Step 1: Mark any invisible elements as unused
544+
if (!continuous || itemsChanged) {
545+
this.removeAndRecycleAllViews()
546+
} else {
564547
for (let i = 0, l = pool.length; i < l; i++) {
565548
view = pool[i]
566549
if (view.nr.used) {
567-
// Update view item index
568-
if (checkItem) {
569-
view.nr.index = items.findIndex(
570-
item => keyField ? item[keyField] === view.item[keyField] : item === view.item,
571-
)
572-
}
573-
574-
// Check if index is still in visible range
575-
if (
576-
view.nr.index === -1 ||
577-
view.nr.index < startIndex ||
578-
view.nr.index >= endIndex
579-
) {
580-
this.unuseView(view)
550+
const viewVisible = view.nr.index >= startIndex && view.nr.index < endIndex
551+
const viewSize = itemSize || sizes[i].size
552+
if (!viewVisible || !viewSize) {
553+
this.removeAndRecycleView(view)
581554
}
582555
}
583556
}
584557
}
585558
586-
const unusedIndex = continuous ? null : new Map()
587-
588-
let item, type, unusedPool
589-
let v
559+
// Step 2: Assign a view and update props for every view that became visible
560+
let item, type
590561
for (let i = startIndex; i < endIndex; i++) {
591562
const elementSize = itemSize || sizes[i].size
592563
if (!elementSize) continue
@@ -597,70 +568,28 @@ export default {
597568
}
598569
view = views.get(key)
599570
600-
if (!itemSize && !sizes[i].size) {
601-
if (view) this.unuseView(view)
602-
continue
603-
}
604-
605-
// No view assigned to item
606571
if (!view) {
572+
// Item just became visible
607573
type = item[typeField]
608-
unusedPool = unusedViews.get(type)
609-
610-
if (continuous) {
611-
// Reuse existing view
612-
if (unusedPool && unusedPool.length) {
613-
view = unusedPool.pop()
614-
view.item = item
615-
view.nr.used = true
616-
view.nr.index = i
617-
view.nr.key = key
618-
view.nr.type = type
619-
} else {
620-
view = this.addView(pool, i, item, key, type)
621-
}
622-
} else {
623-
// Use existing view
624-
// We don't care if they are already used
625-
// because we are not in continous scrolling
626-
v = unusedIndex.get(type) || 0
627-
628-
if (!unusedPool || v >= unusedPool.length) {
629-
view = this.addView(pool, i, item, key, type)
630-
this.unuseView(view, true)
631-
unusedPool = unusedViews.get(type)
632-
}
574+
view = this.getRecycledView(type)
633575
634-
view = unusedPool[v]
576+
if (view) {
635577
view.item = item
636-
view.nr.used = true
637578
view.nr.index = i
638579
view.nr.key = key
639-
view.nr.type = type
640-
unusedIndex.set(type, v + 1)
641-
v++
580+
if (view.nr.type !== type) {
581+
console.warn("Reused view's type does not match pool's type")
582+
}
583+
} else {
584+
// No recycled view available, create a new one
585+
view = this.createView(pool, i, item, key, type)
642586
}
643-
644-
// Assign view to item
645-
views.delete(view.nr.key)
646-
view.nr.used = true
647-
view.nr.index = i
648-
view.nr.key = key
649-
view.nr.type = type
650587
views.set(key, view)
651-
652-
newlyUsedView = true
653588
} else {
654-
view.nr.used = true
655-
view.item = item
656-
}
657-
658-
// Always set item in case it's a new object with the same key
659-
view.item = item
660-
661-
if (newlyUsedView) {
662-
if (i === items.length - 1) this.$emit('scroll-end')
663-
if (i === 0) this.$emit('scroll-start')
589+
if (view.item !== item) { view.item = item }
590+
if (!view.nr.used) {
591+
console.warn("Expected existing view's used flag to be true, got " + view.nr.used)
592+
}
664593
}
665594
666595
// Update position

0 commit comments

Comments
 (0)