perf: update virtuallist

This commit is contained in:
tangjinzhou 2020-10-18 17:37:52 +08:00
parent 3223d43ffb
commit 2c36bf0323
5 changed files with 12 additions and 16 deletions

@ -1 +1 @@
Subproject commit c9c4f31698398d5bafa5ccd80f0cb7c23b1ab608
Subproject commit e705545e455dd81aef96dc293c84f303cff67b21

View File

@ -4,7 +4,7 @@ import RcSelect, { Option, OptGroup, SelectProps as RcSelectProps, BaseProps } f
import { OptionProps as OptionPropsType } from '../vc-select2/Option';
import { defaultConfigProvider } from '../config-provider';
import getIcons from './utils/iconUtil';
import { computed, defineComponent, inject, ref, VNodeChild, App, PropType } from 'vue';
import { computed, defineComponent, inject, ref, VNodeChild, App, PropType, reactive } from 'vue';
import PropTypes from '../_util/vue-types';
import { tuple } from '../_util/type';
@ -109,7 +109,6 @@ const Select = defineComponent({
),
);
const triggerChange = (...args: any[]) => {
console.log(args);
emit('update:value', ...args);
emit('change', ...args);
};
@ -158,7 +157,6 @@ const Select = defineComponent({
} else if (mode === 'combobox') {
mergedNotFound = null;
} else {
console.log(111);
mergedNotFound = renderEmpty('Select') as any;
}
@ -207,7 +205,7 @@ const Select = defineComponent({
dropdownClassName={rcSelectRtlDropDownClassName}
onChange={triggerChange}
>
{slots?.default()}
{slots.default && slots.default()}
</RcSelect>
);
},

View File

@ -81,7 +81,7 @@
// The background colors for active and hover states for things like
// list items or table cells.
@item-active-bg: @primary-1;
@item-hover-bg: @primary-1;
@item-hover-bg: #f5f5f5;
// ICONFONT
@iconfont-css-prefix: anticon;

View File

@ -130,12 +130,11 @@ const List = defineComponent({
if (componentRef.value) {
componentRef.value.scrollTop = alignedTop;
}
state.scrollTop = alignedTop;
}
// ================================ Height ================================
const [setInstance, collectHeight, heights] = useHeights(getKey, null, null);
const [setInstance, collectHeight, heights, heightUpdatedMark] = useHeights(getKey, null, null);
// ========================== Visible Calculation =========================
const calRes = computed(() => {
@ -186,6 +185,7 @@ const List = defineComponent({
// Give cache to improve scroll experience
endIndex = Math.min(endIndex + 1, state.mergedData.length);
return {
heightUpdatedMark,
scrollHeight: itemTop,
start: startIndex,
end: endIndex,
@ -218,7 +218,7 @@ const List = defineComponent({
// But we still need a sync if some special escape
function onFallbackScroll(e: UIEvent) {
const { scrollTop: newScrollTop } = e.currentTarget as Element;
if (newScrollTop !== state.scrollTop) {
if (Math.abs(newScrollTop - state.scrollTop) >= 1) {
syncScrollTop(newScrollTop);
}

View File

@ -1,4 +1,4 @@
import { reactive, Ref, ref, VNodeProps } from 'vue';
import { Ref, ref, VNodeProps } from 'vue';
import { GetKey } from '../interface';
type CacheMap = Record<string, number>;
@ -9,7 +9,7 @@ export default function useHeights<T>(
onItemRemove?: ((item: T) => void) | null,
): [(item: T, instance: HTMLElement) => void, () => void, CacheMap, Ref<number>] {
const instance = new Map<VNodeProps['key'], HTMLElement>();
const heights = reactive<CacheMap>({});
const heights = {};
const updatedMark = ref(0);
let heightUpdateId = 0;
function collectHeight() {
@ -18,19 +18,17 @@ export default function useHeights<T>(
Promise.resolve().then(() => {
// Only collect when it's latest call
if (currentId !== heightUpdateId) return;
let changed = false;
// let changed = false;
instance.forEach((element, key) => {
if (element && element.offsetParent) {
const { offsetHeight } = element;
if (heights[key!] !== offsetHeight) {
changed = true;
//changed = true;
heights[key!] = element.offsetHeight;
}
}
});
if (changed) {
updatedMark.value++;
}
updatedMark.value++;
});
}