Skip to content

Commit 4e70c6d

Browse files
committed
perf: virtual list
1 parent 7aae6f6 commit 4e70c6d

File tree

3 files changed

+125
-114
lines changed

3 files changed

+125
-114
lines changed

components/vc-select/OptionList.tsx

+87-77
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { isValidElement } from '../_util/props-util';
77
import createRef from '../_util/createRef';
88
import type { PropType } from 'vue';
99
import { computed, defineComponent, nextTick, reactive, watch } from 'vue';
10-
import List from '../vc-virtual-list/List';
10+
import List from '../vc-virtual-list';
1111
import type {
1212
OptionsType as SelectOptionsType,
1313
OptionData,
@@ -346,85 +346,95 @@ const OptionList = defineComponent<OptionListProps<SelectOptionsType[number]>, {
346346
onScroll={onScroll}
347347
virtual={virtual}
348348
onMouseenter={onMouseenter}
349-
children={({ group, groupOption, data, label, value }, itemIndex) => {
350-
const { key } = data;
351-
// Group
352-
if (group) {
353-
return (
354-
<div class={classNames(itemPrefixCls, `${itemPrefixCls}-group`)}>
355-
{renderOption ? renderOption(data) : label !== undefined ? label : key}
356-
</div>
357-
);
358-
}
359-
360-
const { disabled, title, children, style, class: cls, className, ...otherProps } = data;
361-
const passedProps = omit(otherProps, omitFieldNameList);
362-
// Option
363-
const selected = values.has(value);
364-
365-
const optionPrefixCls = `${itemPrefixCls}-option`;
366-
const optionClassName = classNames(itemPrefixCls, optionPrefixCls, cls, className, {
367-
[`${optionPrefixCls}-grouped`]: groupOption,
368-
[`${optionPrefixCls}-active`]: activeIndex === itemIndex && !disabled,
369-
[`${optionPrefixCls}-disabled`]: disabled,
370-
[`${optionPrefixCls}-selected`]: selected,
371-
});
372-
373-
const mergedLabel = childrenAsData ? children : label;
374-
375-
const iconVisible =
376-
!menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected;
349+
v-slots={{
350+
default: ({ group, groupOption, data, label, value }, itemIndex) => {
351+
const { key } = data;
352+
// Group
353+
if (group) {
354+
return (
355+
<div class={classNames(itemPrefixCls, `${itemPrefixCls}-group`)}>
356+
{renderOption ? renderOption(data) : label !== undefined ? label : key}
357+
</div>
358+
);
359+
}
377360

378-
const content = mergedLabel || value;
379-
// https://github.com/ant-design/ant-design/issues/26717
380-
let optionTitle =
381-
typeof content === 'string' || typeof content === 'number'
382-
? content.toString()
383-
: undefined;
384-
if (title !== undefined) {
385-
optionTitle = title;
386-
}
361+
const {
362+
disabled,
363+
title,
364+
children,
365+
style,
366+
class: cls,
367+
className,
368+
...otherProps
369+
} = data;
370+
const passedProps = omit(otherProps, omitFieldNameList);
371+
// Option
372+
const selected = values.has(value);
373+
374+
const optionPrefixCls = `${itemPrefixCls}-option`;
375+
const optionClassName = classNames(itemPrefixCls, optionPrefixCls, cls, className, {
376+
[`${optionPrefixCls}-grouped`]: groupOption,
377+
[`${optionPrefixCls}-active`]: activeIndex === itemIndex && !disabled,
378+
[`${optionPrefixCls}-disabled`]: disabled,
379+
[`${optionPrefixCls}-selected`]: selected,
380+
});
381+
382+
const mergedLabel = childrenAsData ? children : label;
383+
384+
const iconVisible =
385+
!menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected;
386+
387+
const content = mergedLabel || value;
388+
// https://github.com/ant-design/ant-design/issues/26717
389+
let optionTitle =
390+
typeof content === 'string' || typeof content === 'number'
391+
? content.toString()
392+
: undefined;
393+
if (title !== undefined) {
394+
optionTitle = title;
395+
}
387396

388-
return (
389-
<div
390-
{...passedProps}
391-
aria-selected={selected}
392-
class={optionClassName}
393-
title={optionTitle}
394-
onMousemove={e => {
395-
if (otherProps.onMousemove) {
396-
otherProps.onMousemove(e);
397-
}
398-
if (activeIndex === itemIndex || disabled) {
399-
return;
400-
}
401-
setActive(itemIndex);
402-
}}
403-
onClick={e => {
404-
if (!disabled) {
405-
onSelectValue(value);
406-
}
407-
if (otherProps.onClick) {
408-
otherProps.onClick(e);
409-
}
410-
}}
411-
style={style}
412-
>
413-
<div class={`${optionPrefixCls}-content`}>
414-
{renderOption ? renderOption(data) : content}
397+
return (
398+
<div
399+
{...passedProps}
400+
aria-selected={selected}
401+
class={optionClassName}
402+
title={optionTitle}
403+
onMousemove={e => {
404+
if (otherProps.onMousemove) {
405+
otherProps.onMousemove(e);
406+
}
407+
if (activeIndex === itemIndex || disabled) {
408+
return;
409+
}
410+
setActive(itemIndex);
411+
}}
412+
onClick={e => {
413+
if (!disabled) {
414+
onSelectValue(value);
415+
}
416+
if (otherProps.onClick) {
417+
otherProps.onClick(e);
418+
}
419+
}}
420+
style={style}
421+
>
422+
<div class={`${optionPrefixCls}-content`}>
423+
{renderOption ? renderOption(data) : content}
424+
</div>
425+
{isValidElement(menuItemSelectedIcon) || selected}
426+
{iconVisible && (
427+
<TransBtn
428+
class={`${itemPrefixCls}-option-state`}
429+
customizeIcon={menuItemSelectedIcon}
430+
customizeIconProps={{ isSelected: selected }}
431+
>
432+
{selected ? '✓' : null}
433+
</TransBtn>
434+
)}
415435
</div>
416-
{isValidElement(menuItemSelectedIcon) || selected}
417-
{iconVisible && (
418-
<TransBtn
419-
class={`${itemPrefixCls}-option-state`}
420-
customizeIcon={menuItemSelectedIcon}
421-
customizeIconProps={{ isSelected: selected }}
422-
>
423-
{selected ? '✓' : null}
424-
</TransBtn>
425-
)}
426-
</div>
427-
);
436+
);
437+
},
428438
}}
429439
></List>
430440
</>

components/vc-tree/NodeList.tsx

+37-36
Original file line numberDiff line numberDiff line change
@@ -269,42 +269,43 @@ export default defineComponent({
269269
itemHeight={itemHeight}
270270
prefixCls={`${prefixCls}-list`}
271271
ref={listRef}
272-
children={(treeNode: FlattenNode) => {
273-
const {
274-
pos,
275-
data: { ...restProps },
276-
title,
277-
key,
278-
isStart,
279-
isEnd,
280-
} = treeNode;
281-
const mergedKey = getKey(key, pos);
282-
delete restProps.key;
283-
delete restProps.children;
284-
285-
const treeNodeProps = getTreeNodeProps(mergedKey, treeNodeRequiredProps);
286-
287-
return (
288-
<MotionTreeNode
289-
{...restProps}
290-
{...treeNodeProps}
291-
title={title}
292-
active={!!activeItem && key === activeItem.key}
293-
pos={pos}
294-
data={treeNode.data}
295-
isStart={isStart}
296-
isEnd={isEnd}
297-
motion={motion}
298-
motionNodes={key === MOTION_KEY ? transitionRange.value : null}
299-
motionType={motionType.value}
300-
onMotionStart={onListChangeStart}
301-
onMotionEnd={onMotionEnd}
302-
treeNodeRequiredProps={treeNodeRequiredProps}
303-
onMousemove={() => {
304-
onActiveChange(null);
305-
}}
306-
/>
307-
);
272+
v-slots={{
273+
default: (treeNode: FlattenNode) => {
274+
const {
275+
pos,
276+
data: { ...restProps },
277+
title,
278+
key,
279+
isStart,
280+
isEnd,
281+
} = treeNode;
282+
const mergedKey = getKey(key, pos);
283+
delete restProps.key;
284+
delete restProps.children;
285+
286+
const treeNodeProps = getTreeNodeProps(mergedKey, treeNodeRequiredProps);
287+
return (
288+
<MotionTreeNode
289+
{...restProps}
290+
{...treeNodeProps}
291+
title={title}
292+
active={!!activeItem && key === activeItem.key}
293+
pos={pos}
294+
data={treeNode.data}
295+
isStart={isStart}
296+
isEnd={isEnd}
297+
motion={motion}
298+
motionNodes={key === MOTION_KEY ? transitionRange.value : null}
299+
motionType={motionType.value}
300+
onMotionStart={onListChangeStart}
301+
onMotionEnd={onMotionEnd}
302+
treeNodeRequiredProps={treeNodeRequiredProps}
303+
onMousemove={() => {
304+
onActiveChange(null);
305+
}}
306+
/>
307+
);
308+
},
308309
}}
309310
></VirtualList>
310311
</>

components/vc-virtual-list/List.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ const List = defineComponent({
398398
virtual,
399399
component: Component = 'div',
400400
onScroll,
401-
children,
401+
children = this.$slots.default,
402402
style,
403403
class: className,
404404
...restProps

0 commit comments

Comments
 (0)