Vue 3 + jsPlumb 实战:如何用JSON数据动态生成可编辑流程图(附完整代码)

Vue 3 + jsPlumb 实战:JSON数据驱动的动态流程图编辑器开发指南

1. 现代流程图编辑器的核心需求

在低代码平台和工作流引擎开发中,动态生成和编辑流程图已成为刚需。传统流程图工具往往只关注UI渲染,而现代开发更需要:

  • 双向数据绑定:视图变化实时同步到数据层
  • 动态配置能力:通过JSON定义流程图结构和样式
  • 可视化编程体验:开发者友好的事件系统和API设计

Vue 3的响应式系统配合jsPlumb的连线引擎,恰好能构建这样的解决方案。下面我们通过完整案例,演示如何实现JSON数据驱动的流程图编辑器。

2. 项目初始化与基础架构

2.1 环境配置

npm install vue@next jsplumb @vueuse/core

2.2 核心数据结构设计

interface FlowNode {
  id: string
  label: string
  type: 'start' | 'end' | 'process' | 'decision'
  position: { x: number; y: number }
  icon?: string
  color?: string
  size?: { width: number; height: number }
}

interface FlowConnection {
  source: string
  target: string
  label?: string
}

interface FlowChart {
  nodes: FlowNode[]
  connections: FlowConnection[]
  viewport?: {
    scale: number
    position: { x: number; y: number }
  }
}

2.3 画布容器组件

<template>
  <div class="flow-editor" ref="container">
    <div 
      v-for="node in nodes" 
      :key="node.id"
      :id="node.id"
      class="flow-node"
      :style="{
        left: `${node.position.x}px`,
        top: `${node.position.y}px`,
        backgroundColor: node.color || '#fff'
      }"
    >
      <div class="node-icon">{
  
  { node.icon || '⬤' }}</div>
      <div class="node-label">{
  
  { node.label }}</div>
    </div>
  </div>
</template>

<style>
.flow-editor {
  position: relative;
  width: 100%;
  height: 800px;
  background: #f5f5f5;
  overflow: hidden;
}

.flow-node {
  position: absolute;
  min-width: 120px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  cursor: move;
}
</style>

3. jsPlumb集成与动态渲染

3.1 初始化jsPlumb实例

import { ref, onMounted } from 'vue'
import { jsPlumb } from 'jsplumb'

export function useFlowEditor(containerRef) {
  const instance = ref(null)
  const nodes = ref([])
  const connections = ref([])

  onMounted(() => {
    instance.value = jsPlumb.getInstance({
      container: containerRef.value,
      connector: ['Flowchart', { stub: 30, gap: 10 }],
      paintStyle: { stroke: '#909399', strokeWidth: 2 },
      endpointStyle: { fill: '#409EFF', radius: 5 }
    })

    // 使节点可拖拽
    nodes.value.forEach(node => {
      instance.value.draggable(node.id, {
        containment: 'parent',
        stop: (evt) => {
          // 更新节点位置数据
          const node = nodes.value.find(n => n.id === evt.el.id)
          if (node) {
            node.position = { x: evt.pos[0], y: evt.pos[1] }
          }
        }
      })
    })
  })

  return { instance, nodes, connections }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值