antd的Tree控件实现手风琴效果

1,141 阅读1分钟

技术栈

  • antd 4.x
  • react
  • ts

关键属性

  • expandedKeys

image.png

  • onExpand

image.png

代码实现

只有关键部分代码,直接cv无法运行

import React, {Key, useState} from 'react';
import {Tree} from 'antd';
import {DownOutlined} from '@ant-design/icons';
import _ from 'lodash';
import type {ClassInfo} from "@/pages/Student-info-dev/components/Modals/ChangeClass/models";

interface TreeDataItem extends ClassInfo {
  title: string
  key: string
  children: TreeDataItem[]
}

/**
 * @function 生成树形控件所需要的数据
 * @param sourceData
 * @param pId
 */
function createTree(sourceData: TreeDataItem[], pId?: string): TreeDataItem[] {
  return sourceData
    ?.filter((item) => pId === undefined ? item.parentId === '0' : item.parentId === pId)
    ?.map(item => {
      const tempData = item;
      tempData.key = item.id;
      tempData.title = item.name;
      tempData.children = createTree(sourceData, item.id);
      return tempData
    });
}

const TreeSchool: React.FC<{
  treeData: ClassInfo[];
  onSelect: (event: any) => void;
}> = ({
        treeData,
        onSelect
      }) => {

  // 当前展开的节点
  const [openNode, setOpenNode] = useState<Key[]>([]);

  /**
   * @event 实现数结构的手风琴效果
   * @param expandedKeys
   */
  const onExpand = (expandedKeys: Key[]) => {
    if (expandedKeys.length > 1) {
      setOpenNode([expandedKeys[0], expandedKeys[expandedKeys.length - 1]])
    } else {
      setOpenNode(expandedKeys)
    }
  };

  return (
    <Tree
      expandedKeys={openNode}
      onExpand={onExpand}
      switcherIcon={<DownOutlined/>}
      treeData={createTree(treeData as TreeDataItem[])}
      onSelect={(key, event) => onSelect(event)}
    />
  )
};

/**
 * @description
 *  - 此处性能优化必不可少
 *  - 如果没有会造成用户每次点击树形控件都会重新渲染组件,导致只要一点击树形控件就会自动闭合
 */
export default React.memo(TreeSchool, (prevProps, nextProps) => {
  return _.isEqual(prevProps.treeData, nextProps.treeData);
})