更新记录
1.0.0(2025-03-12)
主要改进: 添加了可配置的垂直间距(levelHeight) 添加了最小水平间距限制(minHorizontalSpacing) 使用贝塞尔曲线(Bezier curve)使连线更平滑 连线现在是曲线而不是直线,视觉效果更好 这样你就可以: 通过 levelHeight 控制垂直方向的间距 通过 minHorizontalSpacing 确保节点不会靠得太近 获得更平滑的连接线效果 如果你想要更精确的控制,还可以: 添加连线的曲率控制 添加节点大小的配置 实现自动布局算法以优化节点分布
平台兼容性
Vue2 | Vue3 |
---|---|
√ | × |
App | 快应用 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 |
---|---|---|---|---|---|---|
HBuilderX 3.93 | × | × | × | × | × | × |
钉钉小程序 | 快手小程序 | 飞书小程序 | 京东小程序 | 鸿蒙元服务 |
---|---|---|---|---|
× | × | × | × | × |
H5-Safari | Android Browser | 微信浏览器(Android) | QQ浏览器(Android) | Chrome | IE | Edge | Firefox | PC-Safari |
---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | √ | √ | √ | √ |
Learning Path Map 学习路径图组件
一个基于 Vue2 的 UniApp 学习路径图组件,用于可视化展示学习进度和课程路径。
功能特点
- 🌲 支持树形数据结构
- 📱 适配移动端
- 🎨 自动布局计算
- 🔄 平滑的曲线连接
- 🎯 多状态节点显示(已完成/已解锁/未解锁)
- 👆 支持节点点击交互
使用方法
1. 引入组件
vue
import LearningPathMap from '@/components/LearningPathMap.vue';
export default {
components: {
LearningPathMap
}
}
1. 数据格式
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
tree-data | Object | - | 树形数据结构,必填 |
svg-width | Number | 300 | SVG 容器宽度 |
svg-height | Number | 500 | SVG 容器高度 |
level-height | Number | 100 | 层级间垂直距离 |
min-horizontal-spacing | Number | 80 | 最小水平节点间距 |
事件
事件名 | 参数 | 说明 |
---|---|---|
node-click | node | 节点点击事件,返回节点数据 |
节点状态说明
- 绿色 (#4CAF50): 已完成节点
- 橙色 (#FF9800): 已解锁但未完成节点
- 灰色 (#CCCCCC): 未解锁节点
- 蓝色边框 (#2196F3): 当前学习节点
示例代码
<template>
<view class="container">
<view class="title">我的学习进度</view>
<LearningPathMap :tree-data="treeData" :svg-width="svgWidth" :svg-height="svgHeight" :level-height="60"
:min-horizontal-spacing="100" @node-click="onNodeClick" />
</view>
</template>
<script>
export default {
data() {
return {
svgWidth: 350,
svgHeight: 600,
treeData: {
label: '入门',
completed: true,
unlocked: true,
children: [{
label: '基础',
completed: true,
unlocked: true,
children: [{
label: '进阶',
completed: false,
unlocked: true,
current: true,
children: [{
label: '高级',
completed: false,
unlocked: false,
children: [{
label: '专家',
completed: false,
unlocked: false
}]
}]
}]
},
{
label: '分支1',
completed: true,
unlocked: true,
children: [{
label: '分支2',
completed: false,
unlocked: true,
children: [{
label: '分支3',
completed: false,
unlocked: false
}]
}]
}
]
}
};
},
onLoad() {
// 获取屏幕宽度,设置合适的 SVG 尺寸
const systemInfo = uni.getSystemInfoSync();
this.svgWidth = systemInfo.windowWidth * 0.9;
},
methods: {
onNodeClick(node) {
if (!node.unlocked) {
uni.showToast({
title: '该课程尚未解锁',
icon: 'none'
});
return;
}
uni.showToast({
title: `点击了${node.label}课程`,
icon: 'none'
});
// 这里可以跳转到对应的学习页面
// uni.navigateTo({
// url: `/pages/course/detail?id=${node.id}`
// });
}
}
};
</script>
<style>
.container {
padding: 20px;
}
.title {
font-size: 18px;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
}
</style>
自适应处理
组件会自动适应容器宽度,建议在 onLoad
生命周期中设置适当的宽度:
javascript
onLoad() {
const systemInfo = uni.getSystemInfoSync();
this.svgWidth = systemInfo.windowWidth 0.9;
}
注意事项
- 确保父容器具有明确的宽度和高度
- 节点数量过多时,建议适当增加 SVG 容器的宽度和高度
- 可以通过调整
level-height
和min-horizontal-spacing
优化布局 - 组件依赖 SVG,确保运行环境支持 SVG 渲染
自定义样式
组件使用 scoped style,如需自定义样式,可覆盖以下类名:
css
.learning-path-map {
/ 容器样式 /
}
.legend {
/ 图例容器样式 /
}
.legend-item {
/ 图例项样式 /
}
.legend-color {
/ 图例颜色块样式 /
}