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 ================================
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);

View File

@ -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<string, number>;
type CacheMap = Ref<Record<string, number>>;
export default function useHeights<T>(
mergedData: ComputedRef<any[]>,
getKey: GetKey<T>,
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<Symbol>] {
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;
function collectHeight() {
heightUpdateId += 1;
@ -22,9 +28,10 @@ export default function useHeights<T>(
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<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(
containerRef: Ref<Element | undefined>,
mergedData: ComputedRef<any[]>,
heights: Data,
heights: Ref<Data>,
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;