代码演示
如何引入
import { TreeSelect } from '@douyinfe/semi-ui';
基本用法
最简单的用法,默认为单选模式,每一级菜单项均可选择。
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
}
];
return (
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
placeholder="请选择"
/>
);
};
多选
设置 multiple
,可以进行多选。多选情况下所有子项都被选择时,自动勾选显示其父项。
通过 leafOnly
(>= v0.32.0) 属性,可以设置只展示叶子节点,同时 onChange 的回调入参也会只有叶子节点的值。
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
{
label: 'Chengdu',
value: 'Chengdu',
key: '0-0-2',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0'
}
]
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0'
},
{
label: 'Canada',
value: 'Canada',
key: '1-1'
}
]
}
];
return (
<div>
<TreeSelect
style={{ width: 300 }}
multiple
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
placeholder="请选择"
/>
<br/>
<br/>
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
multiple
leafOnly
placeholder="只渲染叶子节点"
/>
<br/>
<br/>
</div>
);
};
限制标签展示数量
在多选的场景中,利用 maxTagCount
可以限制展示的标签数量,超出部分将以 +N 的方式展示。
使用 showRestTagsPopover
(>= v2.22.0) 可以设置在超出 maxTagCount
后,hover +N 是否显示 Popover,默认为 false
。并且,还可以在 restTagsPopoverProps
属性中配置 Popover。
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
{
label: 'Chengdu',
value: 'Chengdu',
key: '0-0-2',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0'
}
]
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0'
},
{
label: 'Canada',
value: 'Canada',
key: '1-1'
}
]
}
];
const textStyle = { margin: '20px 0 10px' };
return (
<div>
<h4 style={textStyle}>maxTagCount=2:</h4>
<TreeSelect
multiple
maxTagCount={2}
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
placeholder="当选中标签超过两个将折叠"
defaultValue={['Beijing', 'Chengdu', 'Canada']}
/>
<h4 style={textStyle}>maxTagCount=2, showRestTagsPopover:</h4>
<TreeSelect
showRestTagsPopover={true}
restTagsPopoverProps={{ position: 'top' }}
multiple
maxTagCount={2}
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
placeholder="hover +N 查看"
defaultValue={['Beijing', 'Chengdu', 'Canada']}
/>
</div>
);
};
可搜索的
通过设置 filterTreeNode
属性可支持搜索功能。默认对 label
值进行搜索,可通过 treeNodeFilterProp
更改。
如果只希望展示过滤后的结果,可以设置 showFilteredOnly
。
import React from 'react';
import { TreeSelect, Switch } from '@douyinfe/semi-ui';
class Demo extends React.Component {
constructor() {
super();
this.state = {
showFilteredOnly: false,
};
this.onChange = this.onChange.bind(this);
}
onChange(showFilteredOnly) {
this.setState({ showFilteredOnly });
}
render() {
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0'
}
]
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0'
},
{
label: 'Canada',
value: 'Canada',
key: '1-1'
}
]
}
];
const { showFilteredOnly } = this.state;
return (
<>
<span>showFilteredOnly</span>
<Switch
checked={showFilteredOnly}
onChange={this.onChange}
size="small"
/>
<br/>
<br/>
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
filterTreeNode
showFilteredOnly={showFilteredOnly}
placeholder="单选可搜索的"
/>
<br/>
<br/>
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
multiple
filterTreeNode
maxTagCount={2}
showFilteredOnly={showFilteredOnly}
placeholder="多选可搜索的"
searchPlaceholder="请输入关键字开始搜索"
/>
<br/>
<br/>
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
multiple
filterTreeNode
maxTagCount={2}
showFilteredOnly={showFilteredOnly}
placeholder="搜索框autofocus"
searchPlaceholder="autofocus"
searchAutoFocus
/>
</>
);
}
}
搜索框位置
可以使用 searchPosition
来设置搜索框的位置,可选: dropdown
(默认)、trigger
。
当输入框位于 trigger 时:
- 搜索框占位符由
placeholder
控制; showClear=true
时,点击输入框的清空按钮,将同时清空 inputValue 和 value。
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0'
}
]
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0'
},
{
label: 'Canada',
value: 'Canada',
key: '1-1'
}
]
}
];
return (
<>
<TreeSelect
searchPosition="trigger"
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
filterTreeNode
placeholder="单选"
/>
<br />
<br />
<TreeSelect
searchPosition="trigger"
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
multiple
filterTreeNode
maxTagCount={2}
placeholder="多选"
/>
</>
);
};
尺寸大小
可以通过 size
设置尺寸大小,可选: 'small'、'default'、'large'
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
}
];
return (
<div>
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
multiple
size="small"
placeholder="small"
/>
<br />
<br />
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
multiple
size="default"
placeholder="default"
/>
<br />
<br />
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
multiple
size="large"
placeholder="large"
/>
</div>
);
};
默认展开
defaultExpandAll
和 expandAll
均可以设置 TreeSelect
的默认展开/收起状态。二者的区别是,defaultExpandAll
只在初始化时生效,而 expandAll
不仅会在初始化时生效,当数据(treeData
)发生动态更新时,expandAll
也仍然生效。
其中,expandAll
是从 1.30.0 开始支持的。
在下面的 demo 中,TreeData
更新后,defaultExpandAll
失效,expandAll
仍然生效。
import React, { useEffect, useState } from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
}
];
const [data, setData] = useState([]);
useEffect(() => {
setTimeout(() => setData(treeData), 500);
}, []);
return (
<>
<TreeSelect
style={{ width: 300, marginBottom: 20 }}
expandAll
treeData={data}
placeholder="expandAll"
/>
<TreeSelect
style={{ width: 300 }}
defaultExpandAll
treeData={data}
placeholder="defaultExpandAll"
/>
</>
);
};
禁用
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
}
];
return (
<div>
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
disabled
placeholder="禁用下拉菜单"
/>
<br />
<br />
<TreeSelect
style={{ width: 300 }}
defaultValue={'Shanghai'}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
disabled
/>
<br />
<br />
<TreeSelect
style={{ width: 300 }}
defaultValue={['Shanghai', 'North America']}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
multiple
disabled
/>
</div>
);
};
严格禁用
version: >= 1.30.0
可以使用 disableStrictly
来开启严格禁用。开启严格禁用后,当节点是 disabled 的时候,则不能通过子级或者父级的关系改变选中状态。
以下面的 demo 为例,节点"中国"开启了严格禁用,因此,当我们改变其父节点"亚洲"的选中状态时,也不会影响到节点"中国"的选中状态。
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
disabled: true,
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: '日本',
value: 'Japan',
key: '0-1',
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
}
];
return (
<div>
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
disableStrictly
multiple
defaultValue={['Shanghai']}
/>
</div>
);
};
受控
传入 value
时即为受控组件,可以配合 onChange
使用。
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
class Demo extends React.Component {
constructor() {
super();
this.state = {
value: 'Shanghai'
};
}
onChange(value) {
this.setState({ value });
}
render() {
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
}
];
return (
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
value={this.state.value}
placeholder="请选择"
onChange={e => this.onChange(e)}
/>
);
}
}
节点选中关系
版本:>= 2.5.0
多选时,可以使用 checkRelation
来设置节点之间选中关系的类型,可选:'related'(默认)、'unRelated'。当选中关系为 'unRelated' 时,意味着节点之间的选中互不影响。
import React from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
}
];
return (
<TreeSelect
multiple
defaultValue='Asia'
checkRelation='unRelated'
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
/>
);
};
开启搜索的展开受控
传入 expandedKeys
时即为展开受控组件,可以配合 onExpand
使用。当展开受控时,如果开启 filterTreeNode
并进行搜索是不会再自动展开节点的,此时,节点的展开完全由 expandedKeys
来控制。你可以利用 onSearch
的入参 filteredExpandedKeys
(version: >= 2.6.0) 来实现展开受控时的搜索展开效果。
import React, { useState } from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const [expandedKeys, setExpandedKeys] = useState([]);
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: '日本',
value: 'Japan',
key: '0-1',
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
}
];
return (
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
filterTreeNode
expandedKeys={expandedKeys}
onExpand={expandedKeys => {
setExpandedKeys(expandedKeys);
}}
onSearch={(inputValue, filteredExpandedKeys) => {
setExpandedKeys([...filteredExpandedKeys, ...expandedKeys]);
}}
/>
);
};
虚拟化
列表虚拟化,用于大量树节点的情况。开启后,动画效果将被关闭。
virtualize
是一个包含下列值的对象:
- height: 高度值,如果为 string 必须有计算高度才能被渲染出来,即其父节点有 offsetHeight。建议传入数组。
- width: 宽度值,默认 100%
- itemSize: 每行的treeNode的高度,必传
如果带搜索框,建议开启 showFilteredOnly
减少多余节点的渲染。
import React from 'react';
import { TreeSelect, Button } from '@douyinfe/semi-ui';
class Demo extends React.Component {
constructor() {
super();
this.state = {
gData: [],
total: 0,
};
this.onGen = this.onGen.bind(this);
}
generateData(x = 5, y = 4, z = 3, gData = []) {
// x:每一级下的节点总数。y:每级节点里有y个节点、存在子节点。z:树的level层级数(0表示一级)
function _loop(_level, _preKey, _tns) {
const preKey = _preKey || '0';
const tns = _tns || gData;
const children = [];
for (let i = 0; i < x; i++) {
const key = `${preKey}-${i}`;
tns.push({ label: `${key}-标签`, key: `${key}-key`, value: `${key}-value` });
if (i < y) {
children.push(key);
}
}
if (_level < 0) {
return tns;
}
const __level = _level - 1;
children.forEach((key, index) => {
tns[index].children = [];
return _loop(__level, key, tns[index].children);
});
return null;
}
_loop(z);
function calcTotal(x, y, z) {
const rec = n => (n >= 0 ? x * y ** n-- + rec(n) : 0);
return rec(z + 1);
}
return { gData, total: calcTotal(x, y, z) };
}
onGen() {
const { gData, total } = this.generateData();
this.setState({
gData,
total
});
};
render() {
const style = {
width: 260,
height: 360,
border: '1px solid var(--semi-color-border)'
};
return (
<div style={{ padding: '0 20px' }}>
<Button onClick={this.onGen}>生成数据: </Button>
<span>共 {this.state.total} 个节点</span>
<br/>
<br/>
{this.state.gData.length ? (
<TreeSelect
style={{ width: 300 }}
treeData={this.state.gData}
filterTreeNode
showFilteredOnly
placeholder="Please select"
dropdownStyle={{
// height: 300,
overflow: 'hidden'
}}
virtualize={{
itemSize: 28,
// dropDown height 300 minus search box height minus padding 8 * 2
// or if you set dropdown height, it will fill 100% of rest space
height: 236
}}
/>
) : null}
</div>
);
}
}
动态更新数据
import React from 'react';
import { TreeSelect, Button } from '@douyinfe/semi-ui';
class Demo extends React.Component {
constructor() {
super();
this.state = {
treeData: [],
};
this.add = this.add.bind(this);
}
add() {
let itemLength = Math.floor(Math.random() * 5) + 1;
let treeData = new Array(itemLength).fill(0).map((v, i) => {
let length = Math.floor(Math.random() * 3);
let children = new Array(length).fill(0).map((cv, ci) => {
let child = {
key: `${i}-${ci}`,
label: `Leaf-${i}-${ci}`,
value: `${i}-${ci}`
};
return child;
});
let item = {
key: `${i}`,
label: `Item-${i}`,
value: `${i}`,
children
};
return item;
});
this.setState({ treeData });
}
render() {
return (
<>
<TreeSelect
style={{ width: 300 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={this.state.treeData}
placeholder="请选择"
/>
<br/>
<br/>
<Button onClick={this.add}>
动态改变数据
</Button>
</>
);
}
}
异步加载数据
通过设置 loadData
可以动态加载数据,此时需要在数据中传入 isLeaf
标明叶子节点。
import React, { useState } from 'react';
import { TreeSelect } from '@douyinfe/semi-ui';
() => {
const initialData = [
{
label: 'Expand to load',
value: '0',
key: '0',
},
{
label: 'Expand to load',
value: '1',
key: '1',
},
{
label: 'Leaf Node',
value: '2',
key: '2',
isLeaf: true,
},
];
const [treeData, setTreeData] = useState(initialData);
function updateTreeData(list, key, children) {
return list.map(node => {
if (node.key === key) {
return { ...node, children };
}
if (node.children) {
return { ...node, children: updateTreeData(node.children, key, children) };
}
return node;
});
}
function onLoadData({ key, children }) {
return new Promise(resolve => {
if (children) {
resolve();
return;
}
setTimeout(() => {
setTreeData(origin =>
updateTreeData(origin, key, [
{
label: 'Child Node',
key: `${key}-0`,
},
{
label: 'Child Node',
key: `${key}-1`,
},
]),
);
resolve();
}, 1000);
});
}
return (
<TreeSelect
loadData={onLoadData}
treeData={treeData}
style={{ width: 300 }}
placeholder="请选择"
/>
);
};
自定义 Trigger
如果默认的触发器样式满足不了你的需求,可以用 triggerRender
自定义选择框的展示。
triggerRender 入参如下:
interface TriggerRenderProps {
componentProps: TreeSelectProps;// 所有用户传给 TreeSelect 的 props
disabled: boolean; // 是否禁用 TreeSelect
value: TreeNodeData[]; // 已选中的 node 的数据
inputValue: string; // 当前 input 框的输入值
onClear: e => void; // 用于清空值的函数
placeholder: string; // placeholder
/* 删除单个 item 时调用的函数,以 item 的 key 作为入参,
* 从 v2.32.0 版本开始支持
*/
onRemove: key => void;
/**
* 用于在 Input 框值更新时候启动搜索,当你在 triggerRender 自定义的
* Input 组件值更新时,你应该调用该函数,用于向 TreeSelect 内部
* 同步状态, 使用同时需要设置 filterTreeNode 参数非 false,
* searchPosition 为 'trigger'
* 从 v2.32.0 版本开始支持
*/
onSearch: inputValue => void;
}
import React, { useState, useCallback, useMemo } from 'react';
import { TreeSelect, Button, Tag, TagInput } from '@douyinfe/semi-ui';
function Demo() {
const treeData = useMemo(() => [
{
label: '亚洲',
value: '亚洲',
key: '0',
children: [
{
label: '中国',
value: '中国',
key: '0-0',
children: [
{
label: '北京',
value: '北京',
key: '0-0-0',
},
{
label: '上海',
value: '上海',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: '北美洲',
key: '1',
}
], []);
const onValueChange = useCallback((value) => {
console.log('onChange', value);
});
const renderTrigger = useCallback((props) => {
const { value, onSearch, onRemove, inputValue } = props;
const tagInputValue = value.map(item => item.key);
const renderTagInMultiple = (key) => {
const label = value.find(item => item.key === key).label;
const onCloseTag = (value, e, tagKey) => {
onRemove(tagKey);
};
return <Tag style={{ marginLeft: 2 }} tagKey={key} key={key} onClose={onCloseTag} closable>{label}</Tag>;
};
return (
<TagInput
inputValue={inputValue}
value={tagInputValue}
onInputChange={onSearch}
renderTagItem={renderTagInMultiple}
/>
);
}, []);
return (
<TreeSelect
triggerRender={renderTrigger}
filterTreeNode
searchPosition="trigger"
multiple
treeData={treeData}
placeholder='Custom Trigger'
onChange={onValueChange}
style={{ width: 300 }}
/>
);
}
自定义渲染已选项
你可以通过 renderSelectedItem 自定义选择框中已选项标签的渲染结构。
- 单选时
renderSelectedItem(treeNode: TreeNodeData) => content:ReactNode
- 多选时
renderSelectedItem(treeNode: TreeNodeData, { index:number, onClose:function }) => { isRenderInTag:bool, content:ReactNode }
- isRenderInTag 为 true 时,会自动将 content 包裹在 Tag 中渲染(带有背景色以及关闭按钮)
- isRenderInTag 为 false 时,将直接渲染返回的 content
import React, { useState, useCallback, useMemo } from 'react';
import { TreeSelect, Tag } from '@douyinfe/semi-ui';
function Demo() {
const [value, setValue] = useState([]);
const treeData = useMemo(() => [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
{
label: '南美洲',
value: 'South America',
key: '2',
},
{
label: '南极洲',
value: 'Antarctica',
key: '3',
},
], []);
return (
<>
<h4>单选</h4>
<TreeSelect
style={{ width: 300 }}
treeData={treeData}
renderSelectedItem={item => item.label}
/>
<h4>多选+ isRenderInTag=true</h4>
<TreeSelect
style={{ width: 300 }}
treeData={treeData}
multiple
renderSelectedItem={(item, { index, onClose }) => ({ content: item.label, isRenderInTag: true })}
/>
<h4>多选 + isRenderInTag=false</h4>
<TreeSelect
style={{ width: 300 }}
treeData={treeData}
multiple
maxTagCount={2}
renderSelectedItem={(item, { index, onClose }) => {
return ({
content: (
<Tag
key={index}
color="white"
closable
onClose={onClose}
>
{item.value}
</Tag>
),
isRenderInTag: false
});
}}
/>
</>
);
}