因为目前在做的这个项目中,ui组件只能使用mui而出现的问题:现在mui没有官方定义好的关于多层级的选择框组件,因此进行了一些尝试。最终实现的样子长这样:
通过使用select和treeview、treeitem三种组件的嵌套实现了,多层级的下拉选择框。实现代码如下:
1.我们先定义一组假数据
let resData: Option[] = [
{
id: 'fruits',
name: 'Fruits',
children: [
{
id: 'apple',
name: 'Apple',
children: [
{ id: '111', name: '111' },
{ id: '222', name: '222' },
],
},
{ id: 'orange', name: 'Orange' },
{ id: 'banana', name: 'Banana' },
],
},
{
id: 'vegetables',
name: 'Vegetables',
children: [
{ id: 'carrot', name: 'Carrot' },
{ id: 'broccoli', name: 'Broccoli' },
],
},
];
2.接着我们建立一个递归方法,用树形数据生成对应的选择项
const renderTree = (node: Option) => (
<TreeItem
key={node.id}
nodeId={node.id}
label={
<FormControlLabel
control={<Checkbox checked={selectedIds.includes(node.id)} onChange={(event) => handleToggle(event, node)} />}
label={node.name}
/>
}>
{Array.isArray(node.children) ? node.children.map((chld) => renderTree(chld)) : null}
</TreeItem>
);
const treeViews = (
<TreeView multiSelect selected={selectedIds} expanded={expanded} onNodeToggle={handleChoose}>
{treeData.map((node) => renderTree(node))}
</TreeView>
);
3.将treeview作为select的选择项
<Select
labelId="demo-multiple-checkbox-label"
id="demo-multiple-checkbox"
multiple
value={selected}
onChange={handleChange}
input={<OutlinedInput label="demo" />}
{treeViews}
</Select>
这样我们就建立了一个最简单的 多层级的下拉选择框。
其中值得注意的点是,如果你的每个节点上都有checkbox来作为选择的标识物,那么要通过自定义TreeView组件的expanded属性和onNodeToggle属性,来重写他每个节点的展开逻辑,不然在点击checkbox的时候他也会进行收缩
const handleChoose = (event: React.SyntheticEvent, nodeIds: string[]) => {
if ((event.target as HTMLDivElement).tagName === 'svg' || (event.target as HTMLDivElement).tagName === 'path') {
setExpanded(nodeIds);
}
};