基于Ant Design的Tree可搜索树形组件
Ant Design中的Tree不能直接拿来满足设计图的样子和需求,按还是基于andt的Tree进行了一些改造。
问题:自定义树节点的展开/折叠图标
antd提供了一个switcherIcon属性,用来自定义图标
但是没有专门区分展开和折叠的图标样子,展开和折叠图标的区别,就是旋转角度而已。所以做不到设计图上的样子。
方案:
icon={<> >}
我是通过在TreeNode节点上的icon属性上加入了2个图标,通过class去控制图标的显示。
生成的节点和搜索功能,都是通过函数的递归调用去完成。
直接上假数据和代码
[{
"knowledgeId": 1,
"knowledgeName": "数与式",
"subjectId": 2,
"phaseId": 2,
"children": [{
"knowledgeId": 2,
"knowledgeName": "有理数",
"subjectId": 2,
"phaseId": 2,
"children": [{
"knowledgeId": 3,
"knowledgeName": "正式和负数",
"subjectId": 2,
"phaseId": 2,
"children": [{
"knowledgeId": 4,
"knowledgeName": "正式、负数的意义",
"subjectId": 2,
"phaseId": 2,
}, {
"knowledgeId": 5,
"knowledgeName": "相反意义的量",
"subjectId": 2,
"phaseId": 2,
}, {
"knowledgeId": 6,
"knowledgeName": "正负数在实际生活",
"subjectId": 2,
"phaseId": 2,
}]
}, {
"knowledgeId": 7,
"knowledgeName": "有理数的初步认识",
"subjectId": 2,
"phaseId": 2,
}]
}]
}, {
"knowledgeId": 8,
"knowledgeName": "方程与不等式",
"subjectId": 2,
"phaseId": 2,
"children": [{
"knowledgeId": 9,
"knowledgeName": "一元二次方程",
"subjectId": 2,
"phaseId": 2,
}]
}])
import React, { useState, useEffect } from 'react';
import style from './fineQuestion.less';
import { Icon, Select, Tree, Input } from "antd";
const { Search } = Input;
const { TreeNode } = Tree;
export default function QuestionMenu(props) {
const [unfolds, setUnfolds] = useState([]);
const [nowSelect, setNowSelect] = useState('');
const [autoExpandParent, setAutoExpandParent] = useState(false);
const [antistop, setAntistop] = useState(false);
//获取需要展开的节点
function getKey(data, cun, value, expandedKeys) {
data.map((item, i) => {
cun = cun + ',' + item.knowledgeId;
if (item.knowledgeName.indexOf(value) > -1) {
expandedKeys.push(...cun.split(','))
}
if (item.hasOwnProperty('children')) {
getKey(item.children, cun, value, expandedKeys);
}
})
}
//输入框关键词搜索
function onChange(e) {
const { value } = e.target;
const expandedKeys = [];
if (value === '') {
setAntistop(false)
return
}
props.treeStructure.map(item => {
let cun = item.knowledgeId;
getKey(item.children, cun, value, expandedKeys);
})
setAntistop(value)
setAutoExpandParent(true)
setUnfolds([...new Set(expandedKeys)])
};
//生成树节点
function recursion(data) {
return <> {
data.map((item, i) => (
item.hasOwnProperty('children') ?
{item.knowledgeName}} key={item.knowledgeId} icon={<> >} >
<> {recursion(item.children)}>
:
{item.knowledgeName}} key={item.knowledgeId} />
))
}
>
}
return (
>}
showIcon={true}
expandedKeys={unfolds}
autoExpandParent={autoExpandParent}
onSelect={(selectedKeys, e) => {
let key = e.node.props.eventKey;
if (unfolds.length === 0) {
setUnfolds(selectedKeys)
return;
}
if (e.node.props.hasOwnProperty('children') && !unfolds.includes(key)) {
//展开
unfolds.push(key)
} else if (e.selectedNodes.length > 0 && !e.selectedNodes[0].props.children) {
// 最后一层
setNowSelect(key)
} else if (unfolds.includes(key)) {
// 收缩
let index = unfolds.indexOf(key)
unfolds.splice(index, 1)
}
setUnfolds(unfolds)
setAutoExpandParent(false)
}}>
{recursion(props.treeStructure)}
)
}
.left {
background : rgba(255, 255, 255, 1);
border-radius: 3px 3px 3px 3px;
height : 100%;
flex : 0 0 250px !important;
max-width : 250px !important;
overflow : hidden;
.keyword {
margin : 20px 0 10px;
padding: 0 13px;
height : 36px;
input {
border-radius: 18px;
padding-left : 16px;
}
span {
font-size: 20px;
right : 30px;
}
}
:global(.ant-tree-node-content-wrapper-close) {
:global(.anticon-minus-circle) {
display: none;
}
}
:global(.ant-tree-node-content-wrapper-open) {
:global(.anticon-plus-circle) {
display: none;
}
}
:global(.ant-tree) {
li {
:global(.ant-tree-node-content-wrapper.ant-tree-node-selected) {
background: #fff !important;
color : #000000 !important;
}
:global(.ant-tree-node-content-wrapper) {
color: #000000;
&:hover {
background: #fff !important;
color : #409EFF !important;
}
}
}
}
}
因为数据量大,可能会接口比较慢,或者这边生成时间比较长,加一个Spin组件,用户体验会好点。
发表评论 (审核通过后显示评论):