vue+jsPlumb+vuedraggable实现可拖拽的流程图

5 篇文章 0 订阅

go.js收费;JointJS有社区版和收费版(Rappid),开源的中文文档相对较少;

jsPlumb有两种版本社区版和收费版,它的中文的开源文档相对多一点。

拖拽的功能不建议使用jQuery和JQuery-ui容易出现问题(例如版本不兼容等),并且要安装两个文件,比较笨重;

1 参考文档

1.1 参考网站

(1)jsPlumb文档

大神中文地址:https://wdd.js.org/jsplumb-chinese-tutorial/#/

大神中文GitHub地址:https://github.com/wangduanduan/jsplumb-chinese-tutorial

社区版官方社区文档(2.X):https://docs.jsplumbtoolkit.com/community-2.x/current/

项目Github地址: https://github.com/jsplumb/jsplumb

(2)vuedraggable文档

npm上的开发文档: https://www.npmjs.com/package/vuedraggable

中文开发文档(版本有点老):https://www.itxst.com/vue-draggable/tutorial.html

(3)参考的项目

VUE+JsPlumb+vuedraggable实现的开源项目:https://gitee.com/xiaoka2017/easy-flow

1.2 安装文件

# 安装jsplumb
cnpm install jsplumb@2.15.6 --save

# 安装vuedraggable
cnpm install vuedraggable@2.24.3 --save

2 结果图

3 源代码

<template>
  <div class="my_jsplumb">
    <draggable class="mj_left" v-on:end="dragWidget">
      <div v-for="(item, index) in navArr" v-bind:key="index">{{item}}</div>
    </draggable>
    <div class="mj_right" id="region_id" ref="region">
      <div v-for="(item, index) in conArr" v-bind:key="index" v-bind:id="item.id" v-bind:style="{'left':item.left, 'top':item.top}">{{item.label}}</div>
    </div>
  </div>
</template>

<script>

import draggable from "vuedraggable"
import { jsPlumb } from 'jsplumb'

export default {
  name: 'MyJsplumb',
  components:{
    draggable
  },
  data: function(){
    return{
      regionId:"#region_id",
      plumbIns: null,
      navArr: new Array(),
      conArr: new Array()      
    }
  },

  created: function(){
    
  },

  mounted: function(){
    this.initData();
    this.initJsplumb();
  },

  methods:{
    initData: function(){
      this.navArr = ["河南大学", "软件学院", "Mason"];

      this.conArr.push({
        id:"con_id_0",
        label: "Mason",
        top: "100px",
        left: "400px"
      });
    },

    initJsplumb: function(){
      this.plumbIns = jsPlumb.getInstance();
      this.$nextTick(() => {
          this.plumbIns.ready(()=>{
            this.addOneAnchor('con_id_0');
          });
      });
    },

    addOneAnchor: function(idStr){
      
      let anchorStyle = {
        isSource: true,
        isTarget: true,
        maxConnections: -1,
        // Set the type of endpoint
        endpoint: 'Dot',

        // Set the style of anchor
        paintStyle: {
          fill: 'pink',
          radius: 8
        },
        hoverPaintStyle: {
          strokeWidth: 2,
          stroke: 'lightblue'
        },

        // Set connection line
        connector: 'StateMachine',
        // The following styles apply only to type flowchart
        // connector: ['Flowchart', {gap: 10, cornerRadius: 5, alwaysRespectStubs: true}],
       
       // Set the style of line
        connectorStyle: {
          strokeWidth: 2,
          stroke: 'green'
        },
        connectorHoverStyle: {
          strokeWidth: 2,
          stroke: 'red'     
        },
        // Set the style of arrow
        connectorOverlays: [ ['Arrow', { width: 14, length: 14, location: 1 }]],
      }

      // Add the anchor of component
      this.plumbIns.addEndpoint(idStr, {anchor: 'Top'}, anchorStyle);
      this.plumbIns.addEndpoint(idStr, {anchor: 'Right'}, anchorStyle);
      this.plumbIns.addEndpoint(idStr, {anchor: 'Bottom'}, anchorStyle);
      this.plumbIns.addEndpoint(idStr, {anchor: 'Left'}, anchorStyle);

      // Set drag and the region
      this.plumbIns.draggable(idStr, {containment: this.regionId});
    },

    dragWidget: function(event){
      // Get position of widget
      var widgetX = event.originalEvent.clientX;
      let widgetY = event.originalEvent.clientY;
      var regionRect = this.$refs.region.getBoundingClientRect();

      // Judge the widget in the region
      if(widgetX>regionRect.left && widgetX<regionRect.left+regionRect.width && widgetY>regionRect.top && widgetY<regionRect.top+regionRect.height){
        // Set the parameter
        let curConId = "new_con_id_"+this.conArr.length;
        let left = widgetX - regionRect.left;
        let top = widgetY - regionRect.top;

        this.conArr.push({
          id: curConId,
          label: event.item.innerText,
          top:top+"px",
          left:left+"px"
        });

        // After delaying DOM updates
        this.$nextTick(()=>{
          this.addOneAnchor(curConId);
        });
      }else{
        alert("请拖拽到内容框中");
      }
    }
  }
}
</script>

<style scoped>
.my_jsplumb{
  position: relative;
  width: 100%;
}

.my_jsplumb>div{
  display: inline-block;
  vertical-align: top;
  position: relative;
  height: 600px;
}

.mj_left{
  width: 10%;
}
.mj_left>div{
  width: 100%;
  height: 40px;
  line-height: 40px;
  margin: 8px 0px;
  background-color: #EBEEF5;
  cursor: pointer;
}

.mj_right{
  width: 88%;
  border: solid 1px #E6A23C;
}

.mj_right>div{
  min-width: 100px;
  position: absolute;
  padding: 8px 10px;
  background-color: #EBEEF5;
  display: inline-block;
  border-radius: 8px;
  cursor: pointer;
}

</style>

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值