Skip to content

Commit

Permalink
优化虚拟列表
Browse files Browse the repository at this point in the history
  • Loading branch information
lyswhut committed Jan 14, 2023
1 parent 850a429 commit 8dff457
Showing 1 changed file with 47 additions and 10 deletions.
57 changes: 47 additions & 10 deletions src/renderer/components/base/VirtualizedList.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<template>
<component :is="containerEl" ref="dom_scrollContainer" :class="containerClass" tabindex="0" style="outline: none; height: 100%; overflow-y: auto; position: relative; display: block; contain: strict;">
<component
:is="containerEl"
ref="dom_scrollContainer"
:class="containerClass"
tabindex="0"
style="outline: none; height: 100%; overflow-y: auto; position: relative; display: block; contain: strict; box-sizing: border-box; will-change: transform;"
>
<component :is="contentEl" :class="contentClass" :style="contentStyle">
<div v-for="item in views" :key="item.key" :style="item.style">
<slot name="default" v-bind="{ item: item.item, index: item.index }" />
Expand All @@ -19,6 +25,24 @@ import {
onBeforeUnmount,
} from 'vue'
/**
* 生成防抖函数
* @param {*} fn
* @param {*} delay
*/
export const debounce = (fn, delay = 100) => {
let timer = null
let _args = null
return function(...args) {
_args = args
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
timer = null
fn.apply(this, _args)
}, delay)
}
}
const easeInOutQuad = (t, b, c, d) => {
t /= d / 2
if (t < 1) return (c / 2) * t * t + b
Expand Down Expand Up @@ -105,12 +129,14 @@ export default {
setup(props, { emit }) {
const views = ref([])
const dom_scrollContainer = ref(null)
let isListScrolling = false
const isListScrollingRef = ref(false)
let startIndex = -1
let endIndex = -1
let scrollTop = -1
let cachedList = []
let cancelScroll = null
let isScrolling = false
let isAutoScrolling = false
let scrollToValue = 0
const createList = (startIndex, endIndex) => {
Expand Down Expand Up @@ -171,7 +197,14 @@ export default {
scrollTop = currentScrollTop
}
const setStopScrollStatus = debounce(() => {
isListScrolling = false
isListScrollingRef.value = false
}, 200)
const onScroll = event => {
if (!isListScrolling) isListScrolling = isListScrollingRef.value = true
setStopScrollStatus()
const currentScrollTop = dom_scrollContainer.value.scrollTop
if (Math.abs(currentScrollTop - scrollTop) > props.itemHeight * 0.6) {
updateView(currentScrollTop)
Expand All @@ -189,15 +222,15 @@ export default {
}
}).then(() => {
if (animate) {
isScrolling = true
isAutoScrolling = true
scrollToValue = scrollTop
cancelScroll = handleScroll(dom_scrollContainer.value, scrollTop, 300, () => {
cancelScroll = null
isScrolling = false
isAutoScrolling = false
onScrollEnd(true)
}, () => {
cancelScroll = null
isScrolling = false
isAutoScrolling = false
onScrollEnd('canceled')
})
} else {
Expand All @@ -217,17 +250,21 @@ export default {
}
const getScrollTop = () => {
return isScrolling ? scrollToValue : dom_scrollContainer.value.scrollTop
return isAutoScrolling ? scrollToValue : dom_scrollContainer.value.scrollTop
}
const handleResize = () => {
window.setTimeout(updateView)
}
const contentStyle = computed(() => ({
display: 'block',
height: props.list.length * props.itemHeight + 'px',
}))
const contentStyle = computed(() => {
const style = {
display: 'block',
height: props.list.length * props.itemHeight + 'px',
}
if (isListScrollingRef.value) style['pointer-events'] = 'none'
return style
})
const handleReset = list => {
cachedList = Array(list.length)
Expand Down

0 comments on commit 8dff457

Please sign in to comment.