From 4e70c6dd775254ae713d8633db2d0363027708e1 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Thu, 23 Dec 2021 23:23:01 +0800 Subject: [PATCH] perf: virtual list --- components/vc-select/OptionList.tsx | 164 +++++++++++++++------------- components/vc-tree/NodeList.tsx | 73 +++++++------ components/vc-virtual-list/List.tsx | 2 +- 3 files changed, 125 insertions(+), 114 deletions(-) diff --git a/components/vc-select/OptionList.tsx b/components/vc-select/OptionList.tsx index 28a2c54cc2..0f6130e0e4 100644 --- a/components/vc-select/OptionList.tsx +++ b/components/vc-select/OptionList.tsx @@ -7,7 +7,7 @@ import { isValidElement } from '../_util/props-util'; import createRef from '../_util/createRef'; import type { PropType } from 'vue'; import { computed, defineComponent, nextTick, reactive, watch } from 'vue'; -import List from '../vc-virtual-list/List'; +import List from '../vc-virtual-list'; import type { OptionsType as SelectOptionsType, OptionData, @@ -346,85 +346,95 @@ const OptionList = defineComponent, { onScroll={onScroll} virtual={virtual} onMouseenter={onMouseenter} - children={({ group, groupOption, data, label, value }, itemIndex) => { - const { key } = data; - // Group - if (group) { - return ( -
- {renderOption ? renderOption(data) : label !== undefined ? label : key} -
- ); - } - - const { disabled, title, children, style, class: cls, className, ...otherProps } = data; - const passedProps = omit(otherProps, omitFieldNameList); - // Option - const selected = values.has(value); - - const optionPrefixCls = `${itemPrefixCls}-option`; - const optionClassName = classNames(itemPrefixCls, optionPrefixCls, cls, className, { - [`${optionPrefixCls}-grouped`]: groupOption, - [`${optionPrefixCls}-active`]: activeIndex === itemIndex && !disabled, - [`${optionPrefixCls}-disabled`]: disabled, - [`${optionPrefixCls}-selected`]: selected, - }); - - const mergedLabel = childrenAsData ? children : label; - - const iconVisible = - !menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected; + v-slots={{ + default: ({ group, groupOption, data, label, value }, itemIndex) => { + const { key } = data; + // Group + if (group) { + return ( +
+ {renderOption ? renderOption(data) : label !== undefined ? label : key} +
+ ); + } - const content = mergedLabel || value; - // https://github.com/ant-design/ant-design/issues/26717 - let optionTitle = - typeof content === 'string' || typeof content === 'number' - ? content.toString() - : undefined; - if (title !== undefined) { - optionTitle = title; - } + const { + disabled, + title, + children, + style, + class: cls, + className, + ...otherProps + } = data; + const passedProps = omit(otherProps, omitFieldNameList); + // Option + const selected = values.has(value); + + const optionPrefixCls = `${itemPrefixCls}-option`; + const optionClassName = classNames(itemPrefixCls, optionPrefixCls, cls, className, { + [`${optionPrefixCls}-grouped`]: groupOption, + [`${optionPrefixCls}-active`]: activeIndex === itemIndex && !disabled, + [`${optionPrefixCls}-disabled`]: disabled, + [`${optionPrefixCls}-selected`]: selected, + }); + + const mergedLabel = childrenAsData ? children : label; + + const iconVisible = + !menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected; + + const content = mergedLabel || value; + // https://github.com/ant-design/ant-design/issues/26717 + let optionTitle = + typeof content === 'string' || typeof content === 'number' + ? content.toString() + : undefined; + if (title !== undefined) { + optionTitle = title; + } - return ( -
{ - if (otherProps.onMousemove) { - otherProps.onMousemove(e); - } - if (activeIndex === itemIndex || disabled) { - return; - } - setActive(itemIndex); - }} - onClick={e => { - if (!disabled) { - onSelectValue(value); - } - if (otherProps.onClick) { - otherProps.onClick(e); - } - }} - style={style} - > -
- {renderOption ? renderOption(data) : content} + return ( +
{ + if (otherProps.onMousemove) { + otherProps.onMousemove(e); + } + if (activeIndex === itemIndex || disabled) { + return; + } + setActive(itemIndex); + }} + onClick={e => { + if (!disabled) { + onSelectValue(value); + } + if (otherProps.onClick) { + otherProps.onClick(e); + } + }} + style={style} + > +
+ {renderOption ? renderOption(data) : content} +
+ {isValidElement(menuItemSelectedIcon) || selected} + {iconVisible && ( + + {selected ? '✓' : null} + + )}
- {isValidElement(menuItemSelectedIcon) || selected} - {iconVisible && ( - - {selected ? '✓' : null} - - )} -
- ); + ); + }, }} > diff --git a/components/vc-tree/NodeList.tsx b/components/vc-tree/NodeList.tsx index 391a1d2969..b90b1e5b8c 100644 --- a/components/vc-tree/NodeList.tsx +++ b/components/vc-tree/NodeList.tsx @@ -269,42 +269,43 @@ export default defineComponent({ itemHeight={itemHeight} prefixCls={`${prefixCls}-list`} ref={listRef} - children={(treeNode: FlattenNode) => { - const { - pos, - data: { ...restProps }, - title, - key, - isStart, - isEnd, - } = treeNode; - const mergedKey = getKey(key, pos); - delete restProps.key; - delete restProps.children; - - const treeNodeProps = getTreeNodeProps(mergedKey, treeNodeRequiredProps); - - return ( - { - onActiveChange(null); - }} - /> - ); + v-slots={{ + default: (treeNode: FlattenNode) => { + const { + pos, + data: { ...restProps }, + title, + key, + isStart, + isEnd, + } = treeNode; + const mergedKey = getKey(key, pos); + delete restProps.key; + delete restProps.children; + + const treeNodeProps = getTreeNodeProps(mergedKey, treeNodeRequiredProps); + return ( + { + onActiveChange(null); + }} + /> + ); + }, }} > diff --git a/components/vc-virtual-list/List.tsx b/components/vc-virtual-list/List.tsx index 4d62a39beb..d9535c16f0 100644 --- a/components/vc-virtual-list/List.tsx +++ b/components/vc-virtual-list/List.tsx @@ -398,7 +398,7 @@ const List = defineComponent({ virtual, component: Component = 'div', onScroll, - children, + children = this.$slots.default, style, class: className, ...restProps