用 flex 布局和 React Hooks 实现一个思惟导图

学习 React 时作的练手项目,基于纯 Hooks 和 flex 布局实现的思惟导图。git

项目地址:RMind,喜欢的话还请点个 star,谢谢啦~ 😉github

在线演示:RMind Democanvas

介绍

Hooks

全部组件都是函数组件,由 Hook 实现事件、状态等的管理。除了 useStateuseEffect 等基本操做外,还实现了:api

  • 利用 useReduceruseContext 的结合,代替 Redux 进行全局状态管理。
  • 将一些重复的 Hook 操做,合并为自定义 Hook 以复用。

flex

项目中第一个实现的功能是思惟导图的绘制,当时图省事没有使用 canvas 或 SVG,而是将导图节点做为 DOM,用 CSS flex 布局。数组

后来发现这样算是给本身挖了个坑,绘制节点链接线时仍是绕不开 canvas,并且由于要获取节点 DOM 的 offset 参数,反而显得有些繁琐。数据结构

不过正由于节点是 DOM,调用 DOM 的 api,很轻易就实现了拖拽功能。最初构想时觉得这会是项目里的难点。函数

数据结构

思惟导图数据结构使用多叉树实现,经过 DFS 进行文件的读写和节点查找。布局

后来想过用平级结构存储,渲染时根据每一个节点保存的子节点 ID 信息,实时构建一棵树出来,可能效率还高一点,不过由于懒就没再深刻研究。学习

优化

  • 用控制台查看流量时,发现“导出功能”的页面耗费 60k,顶得上总加载流量的一半了。考虑到这个功能打开频率不高,利用 React.lazy 将其封装为懒加载组件。测试

  • 使用 useMemo 封装变量,减小了一些没必要要的渲染。

不足

一开始想的是作个基本的增删改就行,作着作着快捷键加上了…主题加上了…撤销重作加上了。context 越写越大,带来了一些组件的重复渲染问题。不过本地测试时还挺流畅,就先搁置不解决了😝


本人经验能力有限,写的代码可能不够美观,可能藏了不少 bug(虽然本身已经抓出来了不少…)。但愿各位高手能不吝赐教~

话很少说,下面放上项目简介

RMind

RMind = React + Mindmap

基于 React Hooks 与 flex 布局,实现了大部分功能的思惟导图。

特色

  • 彻底使用 React Hooks 开发,全部功能均由箭头函数实现
  • 用 flex 布局完成思惟导图排版,惟一用到 canvas 的地方是绘制节点链接线

支持

  • 节点的增删改等基本功能
  • 拖拽操做
  • 撤销/重作
  • 导入及导出 .km(百度脑图) .md(Makrdown) .txt 格式的思惟导图
  • 将导图保存为图片
  • 切换主题

演示

  • 拖拽操做

  • 键盘操做

  • 切换主题

操做方式

鼠标操做

  • 单击选中节点
  • 双击编辑节点文字
  • 拖拽移动节点

键盘操做

功能 按键
切换所选节点 ///
添加子节点 Tab
添加兄弟节点 Enter
删除节点 Backspace/Delete
修改节点文字 F2
切换显示子节点 Space
撤销 Cmd/Ctrl+Z
重作 Cmd/Ctrl+Shift+Z

编辑文字状态下:

功能 按键
取消 Esc
确认 Enter

项目地址

RMind,喜欢的话还请点个 star,谢谢啦~ 😉

在线演示:RMind Demo

相关文章
相关标签/搜索