背景:
1.
前端使用vue2+antv基于easy-flow + jsplumb实现工作流任务的编辑与保存
2.
在实现编辑与多版本回滚时,发现当同一窗体存在一个jsplumb绘制的画布时,再打开新的画布,绘制的工作流定位异常
排查思路:
https://github.com/jsplumb/jsplumb/wiki#multiple
1.
怀疑兼容问题,在antv的 dialog中显示定位异常,排查写在同一层,问题未解决,一个页面不能存在两个canvas
2.
直接定义jsplumb绘制,同一个vue组件多次使用,而内部的canvas的id一致,尝试使用不同的canvasId,发现问题并未解决,实际应该相关,修改使用uuid+canvasId
3.
查看绘制界面元素发现问题, 所有绘制的节点的id都是任务的id, 而同一任务在同一个窗口出现多次相当于document上存在了多个相同id元素
解决方案:
原始canvas结构如下
Canvas.vue
jsPlumbInit () {
this.jsPlumb = jsPlumb.getInstance()
this.jsPlumb.ready(() => {
// 导入默认配置
this.jsPlumb.importDefaults(this.jsplumbSetting)
// 会使整个jsPlumb立即重绘。
this.jsPlumb.setSuspendDrawing(false, true)
this.jsPlumb.setContainer(this.$refs.sEfContainer)
// 初始化节点
this.loadEasyFlow()
})
Node.vue
1. 双向绑定的node的循环绘制中 node的id => getRealId(node.id)
<div id=”canvasId” >
<template v-for=”node in data.nodeList”>
<node :id=”getRealId(node.id)”>
</node>
</template>
</div>
2. 绘制line的from => getRealId(to) 和to => getRealId(from)
// 初始化连线
for (let i = 0; i < this.data.lineList.length; i++) {
const line = this.data.lineList[i]
const connParam = {
source: this.nodeRealId(line.from),
target: this.nodeRealId(line.to),
label: line.from === line.to ? '自依赖' : '',
connector: this.jsplumbSetting.Connector,
// anchors: this.jsplumbSetting.Anchors,
paintStyle: this.jsplumbSetting.PaintStyle
}
this.jsPlumb.connect(connParam, this.jsplumbConnectOptions)
}
this.jsPlumb.repaintEverything()
3. 绑定事件的id => getRealId(id)
// 初始化节点
for (let i = 0; i < this.data.nodeList.length; i++) {
const node = this.data.nodeList[i]
// 设置源点,可以拖出线连接其他节点
this.jsPlumb.makeSource(this.nodeRealId(node.id), lodash.merge(this.jsplumbSourceOptions, {}))
this.jsPlumb.makeTarget(this.nodeRealId(node.id), this.jsplumbTargetOptions)
}
this.jsPlumb.repaintEverything()