目录
引言
Vue Flow 是一个基于 Vue 的流程图库,结合 Vue.js 的组件化优势,可用于创建交互式、可视化的流程图。本文将逐步引导你整合 Vue Flow,涵盖从环境配置到自定义节点、拖拽、连线、删除、JSON 管理和优化,适合初学者和高级开发者。
目的
本文旨在提供一个全面的指南,帮助开发者:
- 理解 Vue Flow 的核心功能和集成流程。
- 实现交互式流程图,包括拖拽、连线和节点管理。
- 掌握数据持久化(保存和导入 JSON),提升项目实用性。
- 优化性能并解决常见问题,确保生产环境稳定。
适用场景
- 工作流管理:设计审批或任务流程。
- 数据可视化:展示组织结构或网络拓扑。
- 工业自动化:模拟设备连接和生产流程。
- 教育工具:可视化算法或逻辑步骤。
- 说明插图:绘制一个工业流程图,包含 “设备1”, “工序1”, “设备2” 节点和连接线。
环境准备
-
项目初始化:使用 Vue 3 + Vite 创建项目。
-
依赖安装:
npm install @vue-flow/core @vue-flow/background @vue-flow/controls @vue-flow/minimap ant-design-vue
@vue-flow/core:核心库。
@vue-flow/background:背景网格。
@vue-flow/controls:交互控制。
@vue-flow/minimap:画布概览。
ant-design-vue:用于按钮样式。

基础组件 (index.vue)
创建 src/components/FlowChart.vue 作为流程图容器。
<template>
<div class="flow-container">
<div class="layout">
<!-- 左侧可选项区域 -->
<div class="sidebar">
<h3>可拖拽节点</h3>
<div
v-for="option in nodeOptions"
:key="option.type"
class="draggable-node"
:data-type="option.type"
draggable="true"
@dragstart="onDragStart"
>
<div class="node-label">{
{ option.label }}</div>
<div class="node-preview-wrapper">
<div :class="['inner-shape', option.shapeClass]">
<div class="label">{
{ option.label }}</div>
</div>
</div>
</div>
</div>
<!-- 右侧 Vue Flow 画布 -->
<div class="flow-area">
<div class="toolbar">
<a-button type="primary" @click="addRandomNode">添加随机节点</a-button>
<!-- <a-button type="danger" @click="deleteSelected">删除选中节点</a-button>-->
<a-button type="default" @click="exportJson">导出 JSON</a-button>
<a-button type="default" @click="saveExportJson">保存流程图</a-button>
</div>
<VueFlow
v-model:nodes="nodes"
v-model:edges="edges"
:node-types="nodeTypes"
:default-edge-options="{
type: 'smoothstep',
animated: true,
markerEnd: { type: 'arrowclosed', color: '#ff0000' },
style: { stroke: '#ff0000', strokeWidth: 2, strokeDasharray: 'none' },
}"
:connection-line-style="{ stroke: '#ff0000', strokeWidth: 2, strokeDasharray: 'none' }"
:fit-view-on-init="true"
:connectable="true"
@drop="onDrop"
@dragover.prevent
@connect="onConnect"
@node-click="onNodeClick"
@node-drag-start="onNodeDragStart"
@node-drag-stop="onNodeDragStop"
@pane-click="onPaneClick"
>
<Background variant="dots" :gap="20" />
<Controls />
<MiniMap />
</VueFlow>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {ref, markRaw, onMounted} from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
import type { NodeTypesObject } from '@vue-flow/core'
import { Background } from '@vue-flow/background'
import { Controls } from '@vue-flow/controls'
import { MiniMap } from '@vue-flow/minimap'
import { message } from 'ant-design-vue'
import DiamondNode from './DiamondNode.vue'
import CircleNode from './CircleNode.vue'
import ImageNode from './ImageNode.vue'
import DeviceNode from './DeviceNode.vue'
import UserNode from './UserNode.vue'
import RoundedRectangleNode from './RoundedRectangleNode.vue'
import { editingNodeId } from './store'
import '@vue-flow/core/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
import '../style/node-styles.css'
const nodes = ref([])
const edges = ref<any>([])
const nodeTypes: NodeTypesObject = {
diamond: markRaw(DiamondNode),
circle: markRaw(CircleNode),
image: markRaw(ImageNode),
user: markRaw(UserNode),
device: markRaw(DeviceNode),
roundedRectangle: markRaw(RoundedRectangleNode),
}
const { addNodes, getNodes, deleteElements,removeNodes } = useVueFlow()
const nodeOptions = r

最低0.47元/天 解锁文章
1万+





