perf: update virtuallist

feat-dayjs
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 { OptionProps as OptionPropsType } from '../vc-select2/Option';
import { defaultConfigProvider } from '../config-provider'; import { defaultConfigProvider } from '../config-provider';
import getIcons from './utils/iconUtil'; 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 PropTypes from '../_util/vue-types';
import { tuple } from '../_util/type'; import { tuple } from '../_util/type';
@ -109,7 +109,6 @@ const Select = defineComponent({
), ),
); );
const triggerChange = (...args: any[]) => { const triggerChange = (...args: any[]) => {
console.log(args);
emit('update:value', ...args); emit('update:value', ...args);
emit('change', ...args); emit('change', ...args);
}; };
@ -158,7 +157,6 @@ const Select = defineComponent({
} else if (mode === 'combobox') { } else if (mode === 'combobox') {
mergedNotFound = null; mergedNotFound = null;
} else { } else {
console.log(111);
mergedNotFound = renderEmpty('Select') as any; mergedNotFound = renderEmpty('Select') as any;
} }
@ -207,7 +205,7 @@ const Select = defineComponent({
dropdownClassName={rcSelectRtlDropDownClassName} dropdownClassName={rcSelectRtlDropDownClassName}
onChange={triggerChange} onChange={triggerChange}
> >
{slots?.default()} {slots.default && slots.default()}
</RcSelect> </RcSelect>
); );
}, },

View File

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

View File

@ -130,12 +130,11 @@ const List = defineComponent({
if (componentRef.value) { if (componentRef.value) {
componentRef.value.scrollTop = alignedTop; componentRef.value.scrollTop = alignedTop;
} }
state.scrollTop = alignedTop; state.scrollTop = alignedTop;
} }
// ================================ Height ================================ // ================================ Height ================================
const [setInstance, collectHeight, heights] = useHeights(getKey, null, null); const [setInstance, collectHeight, heights, heightUpdatedMark] = useHeights(getKey, null, null);
// ========================== Visible Calculation ========================= // ========================== Visible Calculation =========================
const calRes = computed(() => { const calRes = computed(() => {
@ -186,6 +185,7 @@ const List = defineComponent({
// Give cache to improve scroll experience // Give cache to improve scroll experience
endIndex = Math.min(endIndex + 1, state.mergedData.length); endIndex = Math.min(endIndex + 1, state.mergedData.length);
return { return {
heightUpdatedMark,
scrollHeight: itemTop, scrollHeight: itemTop,
start: startIndex, start: startIndex,
end: endIndex, end: endIndex,
@ -218,7 +218,7 @@ const List = defineComponent({
// But we still need a sync if some special escape // But we still need a sync if some special escape
function onFallbackScroll(e: UIEvent) { function onFallbackScroll(e: UIEvent) {
const { scrollTop: newScrollTop } = e.currentTarget as Element; const { scrollTop: newScrollTop } = e.currentTarget as Element;
if (newScrollTop !== state.scrollTop) { if (Math.abs(newScrollTop - state.scrollTop) >= 1) {
syncScrollTop(newScrollTop); 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'; import { GetKey } from '../interface';
type CacheMap = Record<string, number>; type CacheMap = Record<string, number>;
@ -9,7 +9,7 @@ export default function useHeights<T>(
onItemRemove?: ((item: T) => void) | null, onItemRemove?: ((item: T) => void) | null,
): [(item: T, instance: HTMLElement) => void, () => void, CacheMap, Ref<number>] { ): [(item: T, instance: HTMLElement) => void, () => void, CacheMap, Ref<number>] {
const instance = new Map<VNodeProps['key'], HTMLElement>(); const instance = new Map<VNodeProps['key'], HTMLElement>();
const heights = reactive<CacheMap>({}); const heights = {};
const updatedMark = ref(0); const updatedMark = ref(0);
let heightUpdateId = 0; let heightUpdateId = 0;
function collectHeight() { function collectHeight() {
@ -18,19 +18,17 @@ export default function useHeights<T>(
Promise.resolve().then(() => { Promise.resolve().then(() => {
// Only collect when it's latest call // Only collect when it's latest call
if (currentId !== heightUpdateId) return; if (currentId !== heightUpdateId) return;
let changed = false; // let changed = false;
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[key!] !== offsetHeight) {
changed = true; //changed = true;
heights[key!] = element.offsetHeight; heights[key!] = element.offsetHeight;
} }
} }
}); });
if (changed) {
updatedMark.value++; updatedMark.value++;
}
}); });
} }