fix: select can not scroll #4396

close #4396
pull/4479/head
tangjinzhou 2021-08-05 11:41:34 +08:00
parent f35bafb88a
commit 7665cbea01
1 changed files with 63 additions and 61 deletions

View File

@ -145,74 +145,76 @@ const List = defineComponent({
watch( watch(
[inVirtual, useVirtual, () => state.scrollTop, mergedData, heights, () => props.height], [inVirtual, useVirtual, () => state.scrollTop, mergedData, heights, () => props.height],
() => { () => {
if (!useVirtual.value) { nextTick(() => {
calRes.value = { if (!useVirtual.value) {
scrollHeight: undefined, calRes.value = {
start: 0, scrollHeight: undefined,
end: mergedData.value.length - 1, start: 0,
offset: undefined, end: mergedData.value.length - 1,
}; offset: undefined,
return; };
} return;
// Always use virtual scroll bar in avoid shaking
if (!inVirtual.value) {
calRes.value = {
scrollHeight: fillerInnerRef.value?.offsetHeight || 0,
start: 0,
end: mergedData.value.length - 1,
offset: undefined,
};
return;
}
let itemTop = 0;
let startIndex: number | undefined;
let startOffset: number | undefined;
let endIndex: number | undefined;
const dataLen = mergedData.value.length;
const data = mergedData.value;
for (let i = 0; i < dataLen; i += 1) {
const item = data[i];
const key = getKey(item);
const cacheHeight = heights[key];
const currentItemBottom =
itemTop + (cacheHeight === undefined ? props.itemHeight! : cacheHeight);
if (currentItemBottom >= state.scrollTop && startIndex === undefined) {
startIndex = i;
startOffset = itemTop;
} }
// Check item bottom in the range. We will render additional one item for motion usage // Always use virtual scroll bar in avoid shaking
if (currentItemBottom > state.scrollTop + props.height! && endIndex === undefined) { if (!inVirtual.value) {
endIndex = i; calRes.value = {
scrollHeight: fillerInnerRef.value?.offsetHeight || 0,
start: 0,
end: mergedData.value.length - 1,
offset: undefined,
};
return;
} }
itemTop = currentItemBottom; let itemTop = 0;
} let startIndex: number | undefined;
let startOffset: number | undefined;
let endIndex: number | undefined;
const dataLen = mergedData.value.length;
const data = mergedData.value;
for (let i = 0; i < dataLen; i += 1) {
const item = data[i];
const key = getKey(item);
// Fallback to normal if not match. This code should never reach const cacheHeight = heights[key];
/* istanbul ignore next */ const currentItemBottom =
if (startIndex === undefined) { itemTop + (cacheHeight === undefined ? props.itemHeight! : cacheHeight);
startIndex = 0;
startOffset = 0;
}
if (endIndex === undefined) {
endIndex = dataLen - 1;
}
// Give cache to improve scroll experience if (currentItemBottom >= state.scrollTop && startIndex === undefined) {
endIndex = Math.min(endIndex + 1, dataLen); startIndex = i;
calRes.value = { startOffset = itemTop;
scrollHeight: itemTop, }
start: startIndex,
end: endIndex, // Check item bottom in the range. We will render additional one item for motion usage
offset: startOffset, if (currentItemBottom > state.scrollTop + props.height! && endIndex === undefined) {
}; endIndex = i;
}
itemTop = currentItemBottom;
}
// Fallback to normal if not match. This code should never reach
/* istanbul ignore next */
if (startIndex === undefined) {
startIndex = 0;
startOffset = 0;
}
if (endIndex === undefined) {
endIndex = dataLen - 1;
}
// Give cache to improve scroll experience
endIndex = Math.min(endIndex + 1, dataLen);
calRes.value = {
scrollHeight: itemTop,
start: startIndex,
end: endIndex,
offset: startOffset,
};
});
}, },
{ immediate: true }, { immediate: true, flush: 'post' },
); );
// =============================== In Range =============================== // =============================== In Range ===============================