背景:
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()