From 698b684233c6d50e2eae7fc34001ff4f75e60a57 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sun, 5 Dec 2021 00:15:53 +0800 Subject: [PATCH] fix: select cannot scroll #4971 close #4971 --- components/vc-virtual-list/List.tsx | 21 +++++++++++++---- .../vc-virtual-list/hooks/useHeights.tsx | 23 ++++++++++++------- .../vc-virtual-list/hooks/useScrollTo.tsx | 4 ++-- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/components/vc-virtual-list/List.tsx b/components/vc-virtual-list/List.tsx index 0644aba21..4d62a39be 100644 --- a/components/vc-virtual-list/List.tsx +++ b/components/vc-virtual-list/List.tsx @@ -148,7 +148,12 @@ const List = defineComponent({ } // ================================ Height ================================ - const [setInstance, collectHeight, heights] = useHeights(getKey, null, null); + const [setInstance, collectHeight, heights, updatedMark] = useHeights( + mergedData, + getKey, + null, + null, + ); const calRes = ref<{ scrollHeight?: number; @@ -157,9 +162,17 @@ const List = defineComponent({ offset?: number; }>({}); watch( - [inVirtual, useVirtual, () => state.scrollTop, mergedData, heights, () => props.height], + [ + inVirtual, + useVirtual, + () => state.scrollTop, + mergedData, + updatedMark, + heights, + () => props.height, + ], () => { - nextTick(() => { + setTimeout(() => { if (!useVirtual.value) { calRes.value = { scrollHeight: undefined, @@ -191,7 +204,7 @@ const List = defineComponent({ const item = data[i]; const key = getKey(item); - const cacheHeight = heights[key]; + const cacheHeight = heights.value[key]; const currentItemBottom = itemTop + (cacheHeight === undefined ? props.itemHeight! : cacheHeight); diff --git a/components/vc-virtual-list/hooks/useHeights.tsx b/components/vc-virtual-list/hooks/useHeights.tsx index f84d07f66..70bdca9f8 100644 --- a/components/vc-virtual-list/hooks/useHeights.tsx +++ b/components/vc-virtual-list/hooks/useHeights.tsx @@ -1,16 +1,22 @@ -import type { VNodeProps } from 'vue'; -import { reactive } from 'vue'; +import type { VNodeProps, ComputedRef, Ref } from 'vue'; +import { shallowRef, watch, ref } from 'vue'; import type { GetKey } from '../interface'; -type CacheMap = Record; +type CacheMap = Ref>; export default function useHeights( + mergedData: ComputedRef, getKey: GetKey, onItemAdd?: ((item: T) => void) | null, onItemRemove?: ((item: T) => void) | null, -): [(item: T, instance: HTMLElement) => void, () => void, CacheMap] { +): [(item: T, instance: HTMLElement) => void, () => void, CacheMap, Ref] { const instance = new Map(); - const heights = reactive({}); + const heights = shallowRef({}); + const updatedMark = ref(Symbol('update')); + watch(mergedData, () => { + heights.value = {}; + updatedMark.value = Symbol('update'); + }); let heightUpdateId = 0; function collectHeight() { heightUpdateId += 1; @@ -22,9 +28,10 @@ export default function useHeights( instance.forEach((element, key) => { if (element && element.offsetParent) { const { offsetHeight } = element; - if (heights[key!] !== offsetHeight) { + if (heights.value[key!] !== offsetHeight) { //changed = true; - heights[key!] = element.offsetHeight; + updatedMark.value = Symbol('update'); + heights.value[key!] = element.offsetHeight; } } }); @@ -52,5 +59,5 @@ export default function useHeights( } } - return [setInstance, collectHeight, heights]; + return [setInstance, collectHeight, heights, updatedMark]; } diff --git a/components/vc-virtual-list/hooks/useScrollTo.tsx b/components/vc-virtual-list/hooks/useScrollTo.tsx index aab63b933..bfd372917 100644 --- a/components/vc-virtual-list/hooks/useScrollTo.tsx +++ b/components/vc-virtual-list/hooks/useScrollTo.tsx @@ -7,7 +7,7 @@ import type { GetKey } from '../interface'; export default function useScrollTo( containerRef: Ref, mergedData: ComputedRef, - heights: Data, + heights: Ref, props, getKey: GetKey, collectHeight: () => void, @@ -63,7 +63,7 @@ export default function useScrollTo( for (let i = 0; i <= maxLen; i += 1) { const key = getKey(data[i]); itemTop = stackTop; - const cacheHeight = heights[key!]; + const cacheHeight = heights.value[key!]; itemBottom = itemTop + (cacheHeight === undefined ? itemHeight : cacheHeight); stackTop = itemBottom;