react-okr-tree Logoreact-okr-tree

概览

react-okr-tree 是什么、三种布局怎么选、与 vue3-okr-tree 的对应关系。

组织架构图 / OKR 树 React 组件。核心特性是飞书 OKR 的根节点左右双向展开,以及全部由 CSS 伪元素绘制的连接线——组件本体不依赖任何样式框架,外观通过 --okr-* CSS 变量暴露。

它是 vue3-okr-tree(Vue 3 版,v1.13.0)的 React 移植:数据模型、样式表与 API 表都取自同一份真源,功能逐项对齐,只有框架范式强制的部分不同(见迁移说明)。

三种布局

布局怎么开结构典型用途
垂直默认(direction="vertical"根在上,子级向下逐层展开部门层级、审批链
水平direction="horizontal"根在左,子级向右展开,卡片纵向排列深层级、长文本节点
OKR 双向direction="horizontal" + onlyBothTree + leftData根节点左右各挂一棵完整子树目标(O)居中、关键结果分列两侧

OKR 模式下的左树是同一组件的第二棵树:它有独立的伪根(level 0,其顶层节点与右树根同为 level 1),注册表也与右树分开(nodesMap / leftNodesMap),因此左右两棵树允许出现相同的 nodeKey 值。alignRoot(默认 true)让根节点按容器 50% 居中,任意一侧展开或收起都不会推动根节点。

能力一览

内容
渲染定制renderNode / nodeComponent / renderContent 三种节点内容写法,renderExpandBtn / nodeBtnContent 两种展开按钮写法,empty 空态
交互点击选中、右键菜单、展开收起、手风琴、点击节点展开、复选框(父子联动 + 半选)、HTML5 拖拽换父级、完整 WAI-ARIA 键盘导航
数据全树过滤(父随可见后代)、增删改同步回写源数据、updateKeyChildren、懒加载 load、原地变更增量重建
状态非受控(defaultExpandedKeys / currentNodeKey / defaultCheckedKeys)与受控(expandedKeys / currentKey + 对应 onXxxChange)双模
外观6 套内置主题、27 个 --okr-* 外观变量(画布另有 6 个)、unstyled 无样式模式、6 组展开动画、CSS / SVG 双连接线模式(SVG 三种形状)、打印样式、prefers-reduced-motion 降级
组合件OkrTreeGroup(跨实例根对齐)、OkrTreeViewport(画布缩放平移 + PNG / SVG 导出)
查询getVisibleNodes / getNodePath / getNodeEl / getCheckedKeys 等 28 个 ref 方法
工程ESM + CJS + UMD + 单文件 d.ts、SSR 可用、库与文档站共用同一份 API 表

和 Vue 版的关系

API 名称做机械转换,语义与默认值逐字对齐:

Vue 版React 版
node-keyshow-collapsablenodeKeyshowCollapsable(camelCase;两处原版拼写错误刻意保留
@node-click="..."onNodeClick={...}
#default="{ node, data }" 等具名插槽renderNode / renderExpandBtn / empty / renderToolbar render props,作用域参数形状不变
v-model:expanded-keysexpandedKeys + onExpandedKeysChange 成对 props
ref="tree" + this.$refs.tree.filter(v)createRef<OkrTreeHandle>() / useRef + handle.filter(v)
createTypedOkrTree<T>()移除:OkrTree<T> 泛型组件原生提供同等收窄
VueOkrTreePlugin / app.use()移除:默认导出即 OkrTree 组件

两条需要先看一眼的差异:

事件回调少了第三个参数

源项目每个节点事件都带一个 Vue 组件实例参数(nodeComponent),React 没有对应概念,已移除(D2)。需要定位节点 DOM 时用 handle.getNodeEl(data)

同引用原地改数据不再自动感知

Vue 的 deep watch 能同时接住「引用变化」与「原地 push/splice」;React 只在引用变化时重渲染,原地变更根本进不了比较逻辑。默认行为是每次组件渲染时做一次结构脏检查,宿主不重渲染时感知不到,此时调 handle.refreshData()(D7)。详见数据变更检测

接下来读什么

本页目录