lol网站怎么做,做标识的网站 知乎,网站搜索功能实现,哪些行业做网站的多功能点#xff1a;
点击节点前的箭头#xff0c;可以手动展开或折叠该节点的子节点。在搜索框中输入关键词#xff0c;匹配的节点及其父节点会自动展开。清空搜索框后#xff0c;恢复到用户手动控制的展开状态。勾选节点时仍然遵守 最多勾选 6 个节点 和
点击节点前的箭头可以手动展开或折叠该节点的子节点。在搜索框中输入关键词匹配的节点及其父节点会自动展开。清空搜索框后恢复到用户手动控制的展开状态。勾选节点时仍然遵守 最多勾选 6 个节点 和 只能选择同级节点 的限制。
import { Transfer, Tree, Input, message } from antd;
import React, { useState } from react;// 判断是否已选中
const isChecked (selectedKeys, eventKey) selectedKeys.includes(eventKey);// 生成树结构并标记禁用状态
const generateTree (treeNodes [], checkedKeys []) treeNodes.map(({ children, ...props }) ({...props,disabled: checkedKeys.includes(props.key),children: generateTree(children, checkedKeys),}));// 搜索功能过滤树节点并展开到匹配节点
const filterTreeData (treeData, searchValue) {const loop (data) data.map((item) {const match item.title.toLowerCase().includes(searchValue.toLowerCase());const children item.children ? loop(item.children) : [];return {...item,children,isMatch: match || children.some((child) child.isMatch),};}).filter((item) item.isMatch);return loop(treeData);
};// 自定义 TreeTransfer 组件
const TreeTransfer ({ dataSource, targetKeys, ...restProps }) {const transferDataSource [];const [searchValue, setSearchValue] useState();const [expandedKeys, setExpandedKeys] useState([]); // 控制展开的节点// 展平树结构为一维数组function flatten(list []) {list.forEach((item) {transferDataSource.push(item);flatten(item.children);});}flatten(dataSource);// 动态计算需要展开的节点用于搜索const calculateExpandedKeys (treeData) {const keys [];const loop (data) data.forEach((item) {if (item.isMatch) {keys.push(item.key);if (item.children) loop(item.children);}});loop(treeData);return keys;};// 过滤后的树数据const filteredTreeData filterTreeData(dataSource, searchValue);const autoExpandedKeys calculateExpandedKeys(filteredTreeData);// 更新展开状态const handleExpand (newExpandedKeys) {setExpandedKeys(newExpandedKeys);};return (Transfer{...restProps}targetKeys{targetKeys}dataSource{transferDataSource}classNametree-transferrender{(item) item.title}showSelectAll{false}{({ direction, onItemSelect, selectedKeys }) {if (direction left) {const checkedKeys [...selectedKeys, ...targetKeys];return ({/* 搜索框 */}Inputplaceholder搜索节点value{searchValue}onChange{(e) {setSearchValue(e.target.value);setExpandedKeys(autoExpandedKeys); // 搜索时自动展开匹配节点}}style{{ marginBottom: 16 }}/TreeblockNodecheckablecheckStrictlydefaultExpandAllcheckedKeys{checkedKeys}treeData{filteredTreeData}expandedKeys{searchValue ? autoExpandedKeys : expandedKeys} // 根据搜索状态决定展开哪些节点onExpand{handleExpand} // 手动控制展开/折叠onCheck{(_, { node }) {const { key, parentKey } node;// 检查是否在同一层级const isSameLevel checkedKeys.every((k) {const checkedNode transferDataSource.find((item) item.key k);return !checkedNode || checkedNode.parentKey parentKey;});// 检查是否超过最大勾选数量限制const isWithinLimit checkedKeys.length 6 || checkedKeys.includes(key);if (isSameLevel isWithinLimit) {onItemSelect(key, !isChecked(checkedKeys, key));} else {message.warn(!isSameLevel? 只能选择同级节点: 最多只能同时勾选 6 个节点);}}}onSelect{(_, { node }) {const { key, parentKey } node;// 检查是否在同一层级const isSameLevel checkedKeys.every((k) {const checkedNode transferDataSource.find((item) item.key k);return !checkedNode || checkedNode.parentKey parentKey;});// 检查是否超过最大勾选数量限制const isWithinLimit checkedKeys.length 6 || checkedKeys.includes(key);if (isSameLevel isWithinLimit) {onItemSelect(key, !isChecked(checkedKeys, key));} else {message.warn(!isSameLevel? 只能选择同级节点: 最多只能同时勾选 6 个节点);}}}//);}}}/Transfer);
};// 测试数据
const treeData [{key: 0-0,title: Node 0-0,parentKey: null, // 根节点没有父节点},{key: 0-1,title: Node 0-1,parentKey: null,children: [{key: 0-1-0,title: Node 0-1-0,parentKey: 0-1, // 父节点是 0-1},{key: 0-1-1,title: Node 0-1-1,parentKey: 0-1, // 父节点是 0-1},],},{key: 0-2,title: Node 0-3,parentKey: null,},
];// 主应用组件
const App () {const [targetKeys, setTargetKeys] useState([]);const onChange (keys) {setTargetKeys(keys);};return TreeTransfer dataSource{treeData} targetKeys{targetKeys} onChange{onChange} /;
};export default App;