fix: select cannot scroll #4971

close #4971
This commit is contained in:
tangjinzhou 2021-12-05 00:15:53 +08:00
parent 75be0189d6
commit 698b684233
3 changed files with 34 additions and 14 deletions

View File

@ -148,7 +148,12 @@ const List = defineComponent({
} }
// ================================ Height ================================ // ================================ Height ================================
const [setInstance, collectHeight, heights] = useHeights(getKey, null, null); const [setInstance, collectHeight, heights, updatedMark] = useHeights(
mergedData,
getKey,
null,
null,
);
const calRes = ref<{ const calRes = ref<{
scrollHeight?: number; scrollHeight?: number;
@ -157,9 +162,17 @@ const List = defineComponent({
offset?: number; offset?: number;
}>({}); }>({});
watch( watch(
[inVirtual, useVirtual, () => state.scrollTop, mergedData, heights, () => props.height], [
inVirtual,
useVirtual,
() => state.scrollTop,
mergedData,
updatedMark,
heights,
() => props.height,
],
() => { () => {
nextTick(() => { setTimeout(() => {
if (!useVirtual.value) { if (!useVirtual.value) {
calRes.value = { calRes.value = {
scrollHeight: undefined, scrollHeight: undefined,
@ -191,7 +204,7 @@ const List = defineComponent({
const item = data[i]; const item = data[i];
const key = getKey(item); const key = getKey(item);
const cacheHeight = heights[key]; const cacheHeight = heights.value[key];
const currentItemBottom = const currentItemBottom =
itemTop + (cacheHeight === undefined ? props.itemHeight! : cacheHeight); itemTop + (cacheHeight === undefined ? props.itemHeight! : cacheHeight);

View File

@ -1,16 +1,22 @@
import type { VNodeProps } from 'vue'; import type { VNodeProps, ComputedRef, Ref } from 'vue';
import { reactive } from 'vue'; import { shallowRef, watch, ref } from 'vue';
import type { GetKey } from '../interface'; import type { GetKey } from '../interface';
type CacheMap = Record<string, number>; type CacheMap = Ref<Record<string, number>>;
export default function useHeights<T>( export default function useHeights<T>(
mergedData: ComputedRef<any[]>,
getKey: GetKey<T>, getKey: GetKey<T>,
onItemAdd?: ((item: T) => void) | null, onItemAdd?: ((item: T) => void) | null,
onItemRemove?: ((item: T) => void) | null, onItemRemove?: ((item: T) => void) | null,
): [(item: T, instance: HTMLElement) => void, () => void, CacheMap] { ): [(item: T, instance: HTMLElement) => void, () => void, CacheMap, Ref<Symbol>] {
const instance = new Map<VNodeProps['key'], HTMLElement>(); const instance = new Map<VNodeProps['key'], HTMLElement>();
const heights = reactive({}); const heights = shallowRef({});
const updatedMark = ref(Symbol('update'));
watch(mergedData, () => {
heights.value = {};
updatedMark.value = Symbol('update');
});
let heightUpdateId = 0; let heightUpdateId = 0;
function collectHeight() { function collectHeight() {
heightUpdateId += 1; heightUpdateId += 1;
@ -22,9 +28,10 @@ export default function useHeights<T>(
instance.forEach((element, key) => { instance.forEach((element, key) => {
if (element && element.offsetParent) { if (element && element.offsetParent) {
const { offsetHeight } = element; const { offsetHeight } = element;
if (heights[key!] !== offsetHeight) { if (heights.value[key!] !== offsetHeight) {
//changed = true; //changed = true;
heights[key!] = element.offsetHeight; updatedMark.value = Symbol('update');
heights.value[key!] = element.offsetHeight;
} }
} }
}); });
@ -52,5 +59,5 @@ export default function useHeights<T>(
} }
} }
return [setInstance, collectHeight, heights]; return [setInstance, collectHeight, heights, updatedMark];
} }

View File

@ -7,7 +7,7 @@ import type { GetKey } from '../interface';
export default function useScrollTo( export default function useScrollTo(
containerRef: Ref<Element | undefined>, containerRef: Ref<Element | undefined>,
mergedData: ComputedRef<any[]>, mergedData: ComputedRef<any[]>,
heights: Data, heights: Ref<Data>,
props, props,
getKey: GetKey, getKey: GetKey,
collectHeight: () => void, collectHeight: () => void,
@ -63,7 +63,7 @@ export default function useScrollTo(
for (let i = 0; i <= maxLen; i += 1) { for (let i = 0; i <= maxLen; i += 1) {
const key = getKey(data[i]); const key = getKey(data[i]);
itemTop = stackTop; itemTop = stackTop;
const cacheHeight = heights[key!]; const cacheHeight = heights.value[key!];
itemBottom = itemTop + (cacheHeight === undefined ? itemHeight : cacheHeight); itemBottom = itemTop + (cacheHeight === undefined ? itemHeight : cacheHeight);
stackTop = itemBottom; stackTop = itemBottom;