文章目录
- 一、项目简介
- 二、流程图基础结构搭建
-
- [2.1 安装依赖](#2.1 安装依赖)
- [2.2 基础组件结构](#2.2 基础组件结构)
- 三、节点拖拽与连接逻辑
-
- [3.1 拖拽添加节点](#3.1 拖拽添加节点)
- [3.2 jsPlumb 初始化与连接规则](#3.2 jsPlumb 初始化与连接规则)
- 四、节点图标与颜色选择功能
-
- [4.1 节点数据结构](#4.1 节点数据结构)
- [4.2 图标与颜色右键菜单](#4.2 图标与颜色右键菜单)
- [4.3 渲染节点样式](#4.3 渲染节点样式)
- 五、节点与连线删除功能
-
- [5.1 快捷键删除](#5.1 快捷键删除)
- [5.2 删除连线](#5.2 删除连线)
- [六、导入导出 JSON 数据](#六、导入导出 JSON 数据)
-
- [6.1 导出结构](#6.1 导出结构)
- [6.2 导入结构](#6.2 导入结构)
- 七、视图缩放与自动居中
- 八、自动布局拓展方向
- 九、组件封装建议
一、项目简介
本文基于 Vue 3 + jsPlumb 实现一个完整的流程图组件,具备以下功能:
- 支持节点拖拽添加
- 支持节点之间连接与删除
- 节点支持自定义图标与颜色选择
- 支持导入导出 JSON 数据
- 支持视图缩放与自动居中
- 支持快捷键删除、右键菜单操作
- 支持自动布局拓展
- 具备组件封装能力,可复用
二、流程图基础结构搭建
2.1 安装依赖
bash
npm install jsplumb
2.2 基础组件结构
javascript
<template>
<div class="flow-container" ref="container">
<div
v-for="node in nodes"
:key="node.id"
class="flow-node"
:id="node.id"
:style="getNodeStyle(node)"
@contextmenu.prevent="showContextMenu(node, $event)"
>
<div class="icon">{{ node.icon }}</div>
<div class="label">{{ node.label }}</div>
</div>
<context-menu
v-if="context.visible"
:node="context.node"
:x="context.x"
:y="context.y"
@update="updateNode"
@delete="deleteNode"
/>
</div>
</template>
三、节点拖拽与连接逻辑
3.1 拖拽添加节点
javascript
function addNode(label = '新节点') {
const id = 'node-' + Date.now();
nodes.value.push({
id,
label,
icon: '📦',
color: '#409EFF',
left: 200,
top: 150
});
nextTick(() => {
instance.value.draggable(id, { containment: 'parent' });
initEndpoints(id);
});
}
3.2 jsPlumb 初始化与连接规则
javascript
onMounted(() => {
instance.value = jsPlumb.getInstance();
instance.value.bind('connection', info => {
connections.value.push({
source: info.sourceId,
target: info.targetId
});
});
nodes.value.forEach(node => {
instance.value.draggable(node.id, { containment: 'parent' });
initEndpoints(node.id);
});
});
function initEndpoints(id) {
instance.value.addEndpoint(id, {
anchor: 'Right',
isSource: true,
maxConnections: -1
}, commonStyle);
instance.value.addEndpoint(id, {
anchor: 'Left',
isTarget: true,
maxConnections: -1
}, commonStyle);
}
四、节点图标与颜色选择功能
4.1 节点数据结构
javascript
{
id: 'node-1',
label: '开始',
icon: '🟢',
color: '#67C23A',
left: 100,
top: 100
}
4.2 图标与颜色右键菜单
javascript
<!-- ContextMenu.vue -->
<template>
<div class="context-menu" :style="{ left: x + 'px', top: y + 'px' }">
<label>名称:
<input v-model="node.label" />
</label>
<label>图标:
<select v-model="node.icon">
<option>📦</option>
<option>🟢</option>
<option>📄</option>
<option>🔴</option>
</select>
</label>
<label>颜色:
<input type="color" v-model="node.color" />
</label>
<button @click="$emit('delete', node)">删除节点</button>
</div>
</template>
4.3 渲染节点样式
javascript
function getNodeStyle(node) {
return {
left: node.left + 'px',
top: node.top + 'px',
backgroundColor: node.color
};
}
五、节点与连线删除功能
5.1 快捷键删除
javascript
window.addEventListener('keydown', e => {
if (e.key === 'Delete' && selectedNode.value) {
deleteNode(selectedNode.value);
}
});
5.2 删除连线
javascript
instance.value.bind('click', conn => {
instance.value.deleteConnection(conn);
connections.value = connections.value.filter(
c => !(c.source === conn.sourceId && c.target === conn.targetId)
);
});
六、导入导出 JSON 数据
6.1 导出结构
javascript
function exportFlow() {
const data = {
nodes: nodes.value,
connections: connections.value
};
const json = JSON.stringify(data, null, 2);
console.log(json);
}
6.2 导入结构
javascript
function importFlow(json) {
const data = JSON.parse(json);
nodes.value = data.nodes;
connections.value = data.connections;
nextTick(() => {
nodes.value.forEach(n => {
instance.value.draggable(n.id, { containment: 'parent' });
initEndpoints(n.id);
});
connections.value.forEach(conn => {
instance.value.connect({
source: conn.source,
target: conn.target
});
});
});
}
七、视图缩放与自动居中
javascript
function zoomView(scale) {
const container = document.querySelector('.flow-container');
container.style.transform = `scale(${scale})`;
container.style.transformOrigin = '0 0';
}
function centerView() {
const container = document.querySelector('.flow-container');
container.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
八、自动布局拓展方向
可借助 dagre.js 或 elkjs 实现自动布局:
- 自动计算节点位置
- 优化连接路径
- 支持有向图/流程图布局模式
bash
npm install dagre
九、组件封装建议
- 封装为
<FlowEditor />
组件 - 支持
v-model:data
传入节点与连线数据 - 提供
@save
、@connect
、@delete
等事件钩子 - 可组合使用多个视图与工具栏
到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕
