Skip to content

目录树结构算法

产品需求

如何设置目录的存储结构和界面渲染

网络请求

  • 如果文件夹和文件较少,那么应该一次性加载全部的文件和文件夹(好处是,前端直接展开目录,不需要再次发送请求,可能有时间延迟)
  • 如果文件夹和文件很多(例如操作系统中上亿的目录)那么可以先请求根目录,然后展开次级目录时,再请求下层对应的目录,这样首次加载较快,性能更好(对数据库也比较友好)

数据结构示范

以第二种网络请求为例(渲染子节点时,展开树结构)

let dir1 = {
  id: 'asdf',
  name: 'index',
  is_root: false,
  is_folder: true,
  children: ['1111', '2222', '3333'],
};

let dir2 = {
  id: '1111',
  name: 'node_modules',
  is_root: false,
  is_folder: true,
  children: [],
};

let file1 = {
  id: '2222',
  name: 'dist',
  is_root: false,
  is_folder: false,
};

let folders = [
  {id: 2, name: "test-folder2", workspace_id: 1, items: []}
  {id: 6, name: "Untitled folder", workspace_id: 1, items: []}
]

组件渲染示范

文件夹对象

class Folder extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isOpen: false,
      children: [],
    };
  }

  toggleFolderOpen = () => {
    // 点击文件夹,请求文件夹的内容,假设返回的结果已排序,不需要前端排序
    api.getChild(this.props.id).then(res => {
      this.setState({
        children: res.data,
        isOpen: true
      });
    });
  }

  render () {
    const { name, icon } = this.props;
    return (
        <>
        <div onClick={this.toggleFolderOpen}>{name}</div>
        {this.state.isOpen && <List items={this.state.children}/>}
      </>
    );
  }
}

文件对象

class File extends React.Component {
  render () {
    const { name, icon } = this.props;
    return <div>{name}</div>;
  }
}

列表对象

class List extends React.Component {
  render () {
    const { items } = this.props;
    let dom = items.map((item) => {
      const { name, icon, id, type } = item;
      if (type === 'file') {
        return <File name={name} icon={icon} id={id}/>;
      }
      else if (type === 'folder') {
        return <Folder name={name} icon={icon} id={id}/>;
      }
    });
    return <div className="dirent">{dom}</div>;
  }
}

Last update: November 5, 2023