select 超过 100 行数据时才使用 virtual list,这样就不需要每次都加上滚动条宽度了

This commit is contained in:
wuduoyi 2020-08-19 21:54:22 +08:00
parent dd2b5e0959
commit 40b7f5b60d
2 changed files with 86 additions and 85 deletions

View File

@ -759,6 +759,84 @@ export class Select extends React.Component<SelectProps, SelectState> {
const itemHeight = this.state.itemHeight;
// 渲染单个选项
const renderItem = ({index, style}) => {
const item = filtedOptions[index];
const checked =
selectedItem === item ||
!!~selectionValues.indexOf(item[valueField]);
return (
<div
{...getItemProps({
key:
typeof item.value === 'string'
? `${item.label}-${item.value}`
: index,
index,
item,
disabled: item.disabled
})}
style={style}
className={cx(`Select-option`, {
'is-disabled': item.disabled,
'is-highlight': highlightedIndex === index,
'is-active': checked
})}
>
{removable ? (
<a data-tooltip="移除" data-position="left">
<Icon
icon="minus"
className="icon"
onClick={(e: any) => this.handleDeleteClick(e, item)}
/>
</a>
) : null}
{editable ? (
<a data-tooltip="编辑" data-position="left">
<Icon
icon="pencil"
className="icon"
onClick={(e: any) => this.handleEditClick(e, item)}
/>
</a>
) : null}
{checkAll || multiple ? (
<Checkbox
checked={checked}
trueValue={item.value}
onChange={() => {
this.handleChange(item);
}}
disabled={item.disabled}
>
{item.disabled
? item[labelField]
: highlight(
item[labelField],
inputValue as string,
cx('Select-option-hl')
)}
{item.tip}
</Checkbox>
) : (
<span>
{item.disabled
? item[labelField]
: highlight(
item[labelField],
inputValue as string,
cx('Select-option-hl')
)}
{item.tip}
</span>
)}
</div>
);
}
const menu = (
<div ref={this.menu} className={cx('Select-menu')}>
{searchable ? (
@ -798,89 +876,17 @@ export class Select extends React.Component<SelectProps, SelectState> {
</div>
{filtedOptions.length ? (
filtedOptions.length > 100 ? ( // 超过 100 个数据才启用 virtuallist 避免滚动条问题
<VirtualList
height={
filtedOptions.length > 8 ? 280 : filtedOptions.length * itemHeight
}
itemCount={filtedOptions.length}
itemSize={itemHeight}
renderItem={({index, style}) => {
const item = filtedOptions[index];
const checked =
selectedItem === item ||
!!~selectionValues.indexOf(item[valueField]);
return (
<div
{...getItemProps({
key:
typeof item.value === 'string'
? `${item.label}-${item.value}`
: index,
index,
item,
disabled: item.disabled
})}
style={style}
className={cx(`Select-option`, {
'is-disabled': item.disabled,
'is-highlight': highlightedIndex === index,
'is-active': checked
})}
>
{removable ? (
<a data-tooltip="移除" data-position="left">
<Icon
icon="minus"
className="icon"
onClick={(e: any) => this.handleDeleteClick(e, item)}
/>
</a>
) : null}
{editable ? (
<a data-tooltip="编辑" data-position="left">
<Icon
icon="pencil"
className="icon"
onClick={(e: any) => this.handleEditClick(e, item)}
/>
</a>
) : null}
{checkAll || multiple ? (
<Checkbox
checked={checked}
trueValue={item.value}
onChange={() => {
this.handleChange(item);
}}
disabled={item.disabled}
>
{item.disabled
? item[labelField]
: highlight(
item[labelField],
inputValue as string,
cx('Select-option-hl')
)}
{item.tip}
</Checkbox>
) : (
<span>
{item.disabled
? item[labelField]
: highlight(
item[labelField],
inputValue as string,
cx('Select-option-hl')
)}
{item.tip}
</span>
)}
</div>
);
}}
/>
renderItem={renderItem}
/>): (
filtedOptions.map((item, index) => { return renderItem({index}) })
)
) : (
<div className={cx('Select-noResult')}>{__(noResultsText)}</div>
)}

View File

@ -177,12 +177,7 @@ export default class VirtualList extends React.PureComponent<Props, State> {
}
// 自适应宽度
updateRootWidth(isDidUpdate: boolean = false) {
let scrollbarWidth =
window.innerWidth - document.documentElement.clientWidth || 15;
if (isDidUpdate) {
scrollbarWidth = 0;
}
updateRootWidth() {
const itemsDom = this.rootNode.children[0].children;
const containerWidth = this.rootNode.parentElement!.getBoundingClientRect()
.width;
@ -196,7 +191,7 @@ export default class VirtualList extends React.PureComponent<Props, State> {
if (containerWidth >= maxItemWidth) {
this.rootNode.style.width = containerWidth + 'px';
} else {
this.rootNode.style.width = maxItemWidth + scrollbarWidth + 'px';
this.rootNode.style.width = maxItemWidth + 'px';
}
}
@ -258,7 +253,7 @@ export default class VirtualList extends React.PureComponent<Props, State> {
}
componentDidUpdate(_: Props, prevState: State) {
this.updateRootWidth(true);
this.updateRootWidth();
const {offset, scrollChangeReason} = this.state;
if (
prevState.offset !== offset &&