在公司做一个项目,需求是用户根据自己的需求自定义一个流程图,流程图的每一步都用拖拽的方式,自己选择功能和完成连线,一开始就去选技术,找到了几个技术:go.js,g6,vue-task-node,jsplumb,jointjs等,最初想用g6,发现vue+g6的文档不多,开源而用得比较多的是jsplumb,所以我就在github上找到了一个比较适用的——easy-flow-master安利给大家,可以上github上直接搜出来,刚好也符合这个项目的技术框架,是基于vue的。
首先在项目中引用draggable和jsplumb
import draggable from 'vuedraggable'
import {jsPlumb} from 'jsplumb'
import flowNode from './node' //创建子功能块的子组件
import FlowInfo from './info' //子功能块上的信息弹窗
import FlowNodeForm from './node_form' //子功能块上的参数弹窗
import lodash from 'lodash'
data里设置参数
jsPlumb: null,// jsPlumb 实例
easyFlowVisible: true,
jsplumbSetting: {
// 动态锚点、位置自适应
Anchors: ['Top', 'TopCenter', 'TopRight', 'TopLeft', 'Right', 'RightMiddle', 'Bottom', 'BottomCenter', 'BottomRight', 'BottomLeft', 'Left', 'LeftMiddle'],
Container: 'flowContainer',
// 连线的样式 StateMachine、Flowchart
Connector: 'Flowchart',
// 鼠标不能拖动删除线
ConnectionsDetachable: false,
// 删除线的时候节点不删除
DeleteEndpointsOnDetach: false,
// 连线的端点
// Endpoint: ["Dot", {radius: 5}],
Endpoint: ["Dot", {height: 5, width: 5}],
// 线端点的样式
EndpointStyle: {fill: '#E44076', outlineWidth: 1},
// 连线的端点
// Endpoint: ["Dot", {radius: 5}],
// Endpoint: ["Rectangle", {height: 10, width: 10}],
// 线端点的样式
// EndpointStyle: {fill: 'rgba(255,255,255,0)', outlineWidth: 1},
LogEnabled: true,//是否打开jsPlumb的内部日志记录
// 绘制线
PaintStyle: {stroke: '#3D89E9', strokeWidth: 3},
// 绘制箭头
Overlays: [['PlainArrow', {width: 12, length: 12, location: 1}]],
RenderMode: "svg"
},
//拖动时的演示
DragOptions: {
cursor: 'pointer',
zIndex: 2000
},
// jsplumb连接参数
jsplumbConnectOptions: {
isSource: true,
isTarget: true,
// 动态锚点、提供了4个方向 Continuous、AutoDefault
anchor: "Continuous"
},
jsplumbSourceOptions: {
filter: ".flow-node-drag",/*"span"表示标签,".className"表示类,"#id"表示元素id,例如在Node模板中的子功能块加上.flow-node-drag就能画出线,根据你的位置改变你画线的位置*/
filterExclude: false,
anchor: "Continuous",
allowLoopback: false
},
jsplumbTargetOptions: {
filter: ".flow-node-drag",/*"span"表示标签,".className"表示类,"#id"表示元素id*/
filterExclude: false,
anchor: "Continuous",
allowLoopback: false
},
// 是否加载完毕
loadEasyFlowFinish: false,
work_id: "work_id",
offsetX:'',
offsetY:'',
methods里面有几个方法比较常用
jsPlumbInit() //初始化方法,里面bind的一个beforeDrop,再拖拽完成前,这里可以写判断画的线时候符合你们既定的标准,例如不能连自己,不能回环等
loadEasyFlow() //初始化节点
mouseDownHandleelse() //取鼠标放下的x,y轴
mouseMoveHandleelse() //取鼠标经过的x,y轴
mouseUpHandleelse() //取鼠标拿起的x,y轴
deleteLine() //删除连线
changeLine() //改变连线
changeNodeSite() //改变节点位置
addNode() //添加新节点
dataReload() //重新加载数据
hasLine() //是否有该连线
hashOppositeLine() //是否有相反线
在loadEasyFlow中踩过一个坑
jsPlumb.draggable(node.id, {
containment: 'parent',
grid: [10, 10]
})
//这个设置拖拽,容器使它的父节点,如果没有把grid注释掉,后面生成模板切换的时候就出现了bug,功能块能拖动但是线没有跟着移动
清除画布
dataReload() //重新加载一个空数组
保存模板是采用vuex进行模板保存的,切换使用dataReload()重新加载新数据
这是后面完成的一个流程图,基本上一些常见的功能都有了,如果你们有什么好玩的需求可以留言讨论一下