理想是火,点燃熄灭的灯。
首先说下我们的需求:
根据materialUI组件的treeView 来进行前端的模糊搜索
展开所选节点所在的父节点,
同时所匹配到的节点高亮显示
思路:需要先把全部的树节点平铺到一层,
然后根据所选择的子节点(这里场景是搜索,可以是多个子节点),
循环遍历多个所选择的子节点,
然后写一个递归函数,依次传递所选择节点的parsentid,
去跟已经平铺到一层的全部节点进行对比,parsentid === id 则添加到父节点的数组中,
然后再传递 已经匹配上的 全部节点中的 那一个节点 (因为父节点还可能拥有父节点),进行递归。
具体的代码:
import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import TreeView from '@material-ui/lab/TreeView'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; import TreeItem from '@material-ui/lab/TreeItem'; const data = [ { id: 93, label: 'USA', labelCn: 'USA', value: 93, children: [ { id: 94, label: 'US Citizen', labelCn: 'US Citizen', value: 94, parentId: 93, checked: false, }, { id: 95, label: 'Green Card', labelCn: 'Green Card', value: 95, parentId: 93, checked: false, }, { id: 96, label: 'Working Visa', labelCn: 'Working Visa', value: 96, children: [ { id: 97, label: 'H', labelCn: 'H', value: 97, parentId: 96, checked: false, }, { id: 98, label: 'L', labelCn: 'L', value: 98, parentId: 96, checked: false, }, { id: 99, label: 'O', labelCn: 'O', value: 99, parentId: 96, checked: false, children: null, }, { id: 9999, label: 'WW', labelCn: 'WW', value: 9999, parentId: 96, checked: false, children: null, }, ], parentId: 93, checked: false, }, { id: 100, label: 'EAD Card', labelCn: 'EAD Card', value: 100, children: [ { id: 101, label: 'OPT/STEM OPT', labelCn: 'OPT/STEM OPT', value: 101, parentId: 100, checked: false, }, { id: 102, label: 'Asylum', labelCn: 'Asylum', value: 102, parentId: 100, checked: false, }, { id: 103, label: 'H4-EAD', labelCn: 'H4-EAD', value: 103, parentId: 100, checked: false, }, { id: 104, label: 'J2-EAD', labelCn: 'J2-EAD', value: 104, parentId: 100, checked: false, }, { id: 105, label: 'L2-EAD', labelCn: 'L2-EAD', value: 105, parentId: 100, checked: false, }, { id: 106, label: '485 EAD', labelCn: '485 EAD', value: 106, parentId: 100, checked: false, }, ], parentId: 93, checked: false, }, ], parentId: 0, checked: false, }, { id: 107, label: 'Canada', labelCn: 'Canada', value: 107, children: [ { id: 108, label: 'Canadian Citizen', labelCn: 'Canadian Citizen', value: 108, parentId: 107, checked: false, }, { id: 109, label: 'Permanent Resident', labelCn: 'Permanent Resident', value: 109, parentId: 107, checked: false, }, { id: 110, label: 'Open Work Permit', labelCn: 'Open Work Permit', value: 110, parentId: 107, checked: false, }, { id: 111, label: 'Student Visa', labelCn: 'Student Visa', value: 111, parentId: 107, checked: false, }, ], parentId: 0, checked: false, }, { id: 112, label: 'Europe', labelCn: 'Europe', value: 112, children: [ { id: 113, label: 'Citizen', labelCn: 'Citizen', value: 113, parentId: 112, checked: false, }, { id: 114, label: 'Permanent Resident', labelCn: 'Permanent Resident', value: 114, parentId: 112, checked: false, }, { id: 115, label: 'Work permit with restrictions', labelCn: 'Work permit with restrictions', value: 115, parentId: 112, checked: false, }, { id: 116, label: 'Student Visa', labelCn: 'Student Visa', value: 116, parentId: 112, checked: false, }, ], parentId: 0, checked: false, }, ]; const useStyles = makeStyles({ root: { height: 110, flexGrow: 1, maxWidth: 400, }, }); export default function RecursiveTreeView() { const classes = useStyles(); const [expanded, setExpanded] = React.useState([]); const [selected, setSelected] = React.useState([]); const setTreeLabel = (node) => { return ( <div> <span> {node.label} - {node.id} </span> </div> ); }; const renderTree = (nodes) => nodes.map((item, index) => { return ( <TreeItem key={item.id} setChecked={(item) => { setChecked(item); }} nodeId={`${item.id}`} item={item} label={setTreeLabel(item)} > {item.children ? renderTree(item.children) : null} </TreeItem> ); }); const handleToggle = (event, nodeIds) => { setExpanded(nodeIds); }; const handleSelect = (event, nodeIds) => { setSelected(nodeIds); }; let timer = null; const search = (e) => { if (timer) clearTimeout(timer); timer = setTimeout(() => { let value = e.target.value; let expanded = []; let selected = []; if (value) { selected = findNodes(data, value, []); expanded = findParsent(selected); } setSelected(selected.map((n) => String(n.id))); setExpanded(expanded.map((n) => String(n.id))); }, 100); }; const setSpreadTreeData = (tree, data = []) => { for (let i = 0; i < tree.length; i++) { let item = tree[i]; data.push(item); item.children && setSpreadTreeData(item.children, data); } return data; }; const findNodes = (data, value, arr) => { for (let node of data) { if (node.label.toUpperCase().includes(value.toUpperCase())) { arr.push(node); } if (node.children) { findNodes(node.children, value, arr); } } return arr; }; const findParsent = (selected) => { let spreadTreeData = setSpreadTreeData(data); let parsentNodes = []; let dist = (parentId, arr) => { for (let s of spreadTreeData) { if (s.id == parentId) { arr.push(s); if (s.parentId) { dist(s.parentId, arr); } } } return arr; }; for (let s of selected) { parsentNodes = dist(s.parentId, parsentNodes); } return parsentNodes; }; return ( <div> <input type="text" onChange={search} /> <TreeView className={classes.root} defaultCollapseIcon={<ExpandMoreIcon />} defaultExpanded={['root']} defaultExpandIcon={<ChevronRightIcon />} expanded={expanded} selected={selected} onNodeToggle={handleToggle} multiSelect onNodeSelect={handleSelect} > {renderTree(data)} </TreeView> </div> ); }
效果图:
作者: Bill 本文地址: http://biaoblog.cn/info?id=1667549177962
版权声明: 本文为原创文章,版权归 biaoblog 个人博客 所有,欢迎分享本文,转载请保留出处,谢谢!
下一篇:百度翻译api调试