更新记录
1.1.0(2026-06-15)
下载此版本
- 优化颜色控制
- 解决用户端无法显示出思维导图问题
- 思维导图可下载
平台兼容性
uni-app(3.8.0)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
codex-mindmap
基于 uni-app 的高性能思维导图组件,使用原生 Canvas 2D API 绘制,无第三方图表库依赖。支持微信小程序和 H5 双端运行。
特性
- 原生 Canvas 2D 绘制,
requestAnimationFrame 驱动渲染,拖拽缩放流畅
- 根据文字长度自动计算节点宽度,三次贝塞尔曲线连线
- 三种排布模式:向右(
right)、向左(left)、居中发散(center)
- 一指拖拽漫游 + 双指捏合缩放(移动端);鼠标拖拽 + 滚轮缩放(H5)
- 自适应视图(Fit View):自动缩放使整棵树完整停靠在视口内
- 节点展开/收起(折叠子树),点击拾取(AABB 碰撞检测)
- 导出为高清图片(小程序离屏 Canvas / H5 DataURL)
- 支持节点文字换行、自定义颜色
文件结构
uni_modules/codex-mindmap/
├── components/
│ └── codex-mindmap/
│ ├── codex-mindmap.vue # 视图层(Canvas 渲染、手势交互、生命周期)
│ └── layout.js # 布局引擎(纯数学计算,无 DOM 依赖)
├── package.json
├── changelog.md
└── readme.md
基本用法
<template>
<view class="page">
<codex-mindmap
ref="mindmap"
mindMapId="myMindmap"
layoutMode="right"
:fitView="true"
:rawData="treeData"
:contentStyle="{ height: '80vh', background: '#f7f8fa' }"
@node-click="onNodeClick"
/>
</view>
</template>
<script>
export default {
data() {
return {
treeData: {
id: 'root',
topic: '法律服务',
children: [
{
id: 'c1',
topic: '合同审查',
children: [
{ id: 'c1_1', topic: '劳动合同' },
{ id: 'c1_2', topic: '租赁合同' }
]
},
{
id: 'c2',
topic: '法律咨询',
children: [
{ id: 'c2_1', topic: '婚姻家庭' },
{ id: 'c2_2', topic: '债权债务' }
]
}
]
}
}
},
onReady() {
this.$refs.mindmap.initMindMap()
},
methods: {
onNodeClick(node) {
console.log('点击节点:', node.topic)
}
}
}
</script>
注意:需在 onReady 或数据就绪后手动调用 initMindMap() 初始化。
Props
| 属性 |
类型 |
默认值 |
说明 |
mindMapId |
String |
'mindmap-canvas' |
Canvas ID,同一页面多个画布时需设置不同值 |
rawData |
Object |
null |
思维导图树形数据 |
layoutMode |
String |
'center' |
排布方向:'right' / 'left' / 'center' |
fitView |
Boolean |
true |
自适应视图,自动缩放使整棵树完整可见 |
initialZoom |
Number |
1.0 |
初始缩放比例(0.1 ~ 3.0),fitView=false 时生效 |
fitPadding |
Number |
40 |
自适应缩放时的画布四周留白(px) |
contentStyle |
Object |
null |
画布容器样式(宽高、背景色、圆角等),覆盖默认样式 |
textWrap |
Boolean |
false |
节点文字是否允许换行 |
textMaxWidth |
Number |
180 |
节点最大宽度(px),textWrap=true 时生效 |
textLineHeight |
Number |
18 |
节点文字行高(px),textWrap=true 时生效 |
textAlign |
String |
'center' |
节点文字对齐:'center' / 'left' |
nodeBgColor |
String |
'#fff5f5' |
节点背景色 |
nodeBorderColor |
String |
'#ab000f' |
节点边框色 |
lineColor |
String |
'#5C403C' |
连接线颜色 |
Events
| 事件名 |
回调参数 |
说明 |
@node-click |
(nodeData: Object) |
点击节点时触发,返回节点完整数据(含 id、topic、children、x、y 等) |
Methods
| 方法名 |
说明 |
initMindMap() |
初始化思维导图(布局计算 + Canvas 初始化),需在 onReady 或数据就绪后手动调用 |
exportImage() |
导出为高清图片。小程序返回临时文件路径(Promise),H5 返回 DataURL 字符串 |
exportImage 示例
async saveImage() {
try {
const path = await this.$refs.mindmap.exportImage()
// #ifdef MP-WEIXIN
uni.saveImageToPhotosAlbum({
filePath: path,
success: () => uni.showToast({ title: '已保存' })
})
// #endif
// #ifdef H5
// path 为 base64 DataURL,可赋值给 <img> 或触发下载
// #endif
} catch (e) {
console.error('导出失败', e)
}
}
数据结构
rawData 需为嵌套树形 JSON,每个节点包含:
{
"id": "唯一标识",
"topic": "显示文本",
"children": [
{ "id": "子节点1", "topic": "子节点文本" },
{ "id": "子节点2", "topic": "子节点文本", "children": [] }
]
}
id:必填,节点唯一标识
topic:必填,节点显示文本
children:可选,子节点数组
如果节点缺少 id,组件会自动生成随机 ID。
平台兼容性
| 平台 |
支持情况 |
| 微信小程序 |
✅ 主要目标平台 |
| H5 |
✅ 支持(鼠标拖拽 + 滚轮缩放) |
| App(Vue) |
⚠️ 未充分测试 |
| 支付宝/百度等小程序 |
⚠️ 未充分测试 |
注意事项
- 必须手动初始化:组件不会自动渲染,需在
onReady 后调用 this.$refs.mindmap.initMindMap()
- Canvas type="2d":小程序端使用原生 Canvas 2D 接口,微信基础库需 >= 2.9.0
- 真机调试:开发者工具中 Canvas 文字排版和手势事件可能与真机不一致,交互问题请用真机验证
- 大量节点性能:当前碰撞检测为全量树遍历,节点超过 1000 个时建议自行扩展视口剔除(Culling)优化
- H5 端 Canvas:H5 使用
uni.createCanvasContext 兼容方案,不支持 type="2d"