From 82eb7f16ad3f663be602a747b55a78f6b986da30 Mon Sep 17 00:00:00 2001 From: kailong321200875 <321200875@qq.com> Date: Sun, 5 Nov 2023 09:07:15 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=80=91=E5=B8=83?= =?UTF-8?q?=E6=B5=81=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Waterfall/src/Waterfall.vue | 153 ++++++++++++++++----- 1 file changed, 115 insertions(+), 38 deletions(-) diff --git a/src/components/Waterfall/src/Waterfall.vue b/src/components/Waterfall/src/Waterfall.vue index ae648c1..32a0aa7 100644 --- a/src/components/Waterfall/src/Waterfall.vue +++ b/src/components/Waterfall/src/Waterfall.vue @@ -20,10 +20,13 @@ const prop = defineProps({ src: 'src', height: 'height' }), + cols: propTypes.number.def(undefined), loadingText: propTypes.string.def('加载中...'), loading: propTypes.bool.def(false), end: propTypes.bool.def(false), - endText: propTypes.string.def('没有更多了') + endText: propTypes.string.def('没有更多了'), + autoCenter: propTypes.bool.def(true), + layout: propTypes.oneOf(['javascript', 'flex']).def('flex') }) const wrapEl = ref() @@ -37,7 +40,7 @@ const wrapWidth = ref(0) const loadMore = ref() // 首先确定列数 = 页面宽度 / 图片宽度 -const cols = ref(0) +const innerCols = ref(0) const filterData = ref([]) @@ -49,11 +52,11 @@ const filterWaterfall = async () => { const container = unref(wrapEl) as HTMLElement if (!container) return - cols.value = Math.floor(container.clientWidth / (width + gap)) + innerCols.value = prop.cols ?? Math.floor(container.clientWidth / (width + gap)) const length = data.length for (let i = 0; i < length; i++) { - if (i < unref(cols)) { + if (i < unref(innerCols)) { heights.value[i] = data[i][props.height as string] filterData.value.push({ ...data[i], @@ -66,7 +69,7 @@ const filterWaterfall = async () => { let minHeight = heights.value[0] let index = 0 // 找出最小高度 - for (let j = 1; j < unref(cols); j++) { + for (let j = 1; j < unref(innerCols); j++) { if (unref(heights)[j] < minHeight) { minHeight = unref(heights)[j] index = j @@ -83,14 +86,42 @@ const filterWaterfall = async () => { } } wrapHeight.value = Math.max(...unref(heights)) - wrapWidth.value = unref(cols) * (width + gap) - gap + wrapWidth.value = unref(innerCols) * (width + gap) - gap +} + +const flexWaterfall = async () => { + const { width, gap } = prop + const data = prop.data as any[] + await nextTick() + + const container = unref(wrapEl) as HTMLElement + if (!container) return + innerCols.value = prop.cols ?? Math.floor(container.clientWidth / (width + gap)) + + const length = data.length + // 根据列数,创建数组 + const arr = new Array(unref(innerCols)).fill([]) + // 循环data,依次插入到arr中 + for (let i = 0; i < length; i++) { + const index = i % unref(innerCols) + arr[index] = [...arr[index], data[i]] + } + filterData.value = arr +} + +const initLayout = () => { + const { layout } = prop + if (layout === 'javascript') { + filterWaterfall() + } else if (layout === 'flex') { + flexWaterfall() + } } watch( - () => prop.data, - async () => { - await nextTick() - filterWaterfall() + () => [prop.data, prop.cols], + () => { + initLayout() }, { immediate: true @@ -99,7 +130,7 @@ watch( onMounted(() => { if (unref(prop.reset)) { - useEventListener(window, 'resize', debounce(filterWaterfall, 300)) + useEventListener(window, 'resize', debounce(initLayout, 300)) } useIntersectionObserver( unref(loadMore), @@ -117,41 +148,87 @@ onMounted(() => {