第一步:安装jsPlumb

npm i jsplumb

第二步:全局引入

        在main.js 中引入,且挂在Vue事例上

import jsPlumb from 'jsplumb'

Vue.prototype.$jsPlumb = jsPlumb.jsPlumb

第三步:编写组件代码

创建 slsJsPlumbComponent.vue文件

<template>
  <div>
    <div id="container">
      <div class="left1">
        <ul class="left1_ul">
          <li v-for="(item,index) in leftList" :key="'left' + index" :id="item.nodeId" name="source">
            {{item.name}}
          </li>
        </ul>
      </div>

      <div class="right1">
        <ul class="left1_ul">
          <li v-for="(item,index) in rightList" :key="'right' + index" :id="item.nodeId" name="target">
            {{item.name}}
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "slsJsPlumbComponent",
  props:{
    leftList:{ //左边节点数组[{"name":"xxx",nodeId:"l_xxxx"}]
      type:Array
    },
    rightList:{//右边节点数组
      type:Array
    },
    isLink:{//是否可连接
      type:Boolean,
      default:true
    },
    fieldRelas:{//连接的详情
      type:Array
    }
  },
  data(){
    return {
      jsPlumb: this.$jsPlumb.getInstance({
        Container: 'container', // 选择器id
        EndpointStyle: {radius: 0.11, fill: '#999'}, // 端点样式
        PaintStyle: {stroke: '#999', strokeWidth: 2}, // 绘画样式,默认8px线宽  #456
        HoverPaintStyle: {stroke: '#994B0A', strokeWidth: 3 }, // 默认悬停样式  默认为null
        ConnectionOverlays: [ // 此处可以设置所有箭头的样式
          ['Arrow', { // 设置参数可以参考中文文档
            location: 1,
            length: 12,
            paintStyle: {
              stroke: '#999',
              fill: '#999'
            }
          }]
        ],
        Connector: ['Straight'], // 要使用的默认连接器的类型:直线,折线,曲线等
        DrapOptions: {cursor: 'crosshair', zIndex: 2000}
      }), // 缓存实例化的jsplumb对象
      field_rela:[]
    }
  },
  watch:{
    leftList(){
      if(this.isLink){
        this.$nextTick(()=>{
          this.showPlumb()
        })
      }
    },
    fieldRelas(){
      this.$nextTick(()=>{
        this.initConnect()
      })
    }
  },
  methods:{
    showPlumb() {
      // this.jsPlumb =
      let this_ = this
      this.jsPlumb.batch(() => {
        for(let i = 0; i < this_.leftList.length; i++){
          this_.initLeaf(this_.leftList[i].nodeId, 'source');
        }
        for(let j = 0; j < this_.rightList.length; j++){
          this_.initLeaf(this_.rightList[j].nodeId , 'target')
        }
      })

      this.setjsPlumb(true,true);

      //点击连线删除连接
      this.jsPlumb.bind('click',  (conn, originalEvent) => {
        // console.log(conn, originalEvent)
        this.jsPlumb.deleteConnection(conn)
        let remIndex = -1
        for(let i=0;i<this.field_rela.length;i++){
          if("l_"+this.field_rela[i].sls == conn.sourceId){
            remIndex = i
          }
        }
        this.field_rela.splice(remIndex,1)
        this.$emit("getFieldRela",this.field_rela)
      })

      //连线时触发 存储连接信息
      this.jsPlumb.bind('connection',  (conn, originalEvent) => {
        // console.log(conn.sourceId)
        // console.log(conn.targetId)
        this.field_rela.push({"sls":conn.sourceId.replace("l_"),"table_field":conn.targetId.replace("r_")})
        this.$emit("getFieldRela",this.field_rela)
      })

      //右键触发
      /*this.jsPlumb.bind('contextmenu',  (conn, originalEvent) => {
        console.log(conn, originalEvent)
      })*/
    },
    //  初始化规则使其可以连线、拖拽
    initLeaf(id, type) {
      const ins = this.jsPlumb;
      const elem = document.getElementById(id);
      if (type === 'source') {
        ins.makeSource(elem, {
          anchor: [1, 0.5, 0, 0], // 左 上 右 下
          allowLoopback: false, //允许回连
          maxConnections: 1 //最大连接数(-1表示不限制)
        })
      } else {
        ins.makeTarget(elem, {
          anchor: [0, 0.5, 0, 0],
          allowLoopback: false,
          maxConnections: 1
        })
      }
    },
    setjsPlumb(sourceFlag, targetFlag){
      const source = document.getElementsByName('source')
      const target = document.getElementsByName('target')

      this.jsPlumb.setSourceEnabled(source, sourceFlag)
      this.jsPlumb.setTargetEnabled(target, targetFlag)
      this.jsPlumb.setDraggable(source, false) // 是否支持拖拽
      this.jsPlumb.setDraggable(target, false) // 是否支持拖拽
    },
    clearAllNode(){
      this.jsPlumb.deleteEveryConnection()
    },
    initConnect(){
      const jsplumbConnectOptions ={
        isSource: true,
        isTarget: true,
        // 动态锚点、提供了4个方向 Continuous、AutoDefault
        anchor: "Continuous",
      }
      this.jsPlumb.deleteEveryConnection()
      for (var i = 0; i < this.fieldRelas.length; i++) {
        let line = this.fieldRelas[i]
        this.jsPlumb.connect({
          source: 'll_'+line.sls,
          target: 'rr_'+line.table_field,
        }, jsplumbConnectOptions);
      }
    }
  }
}
</script>

<style scoped>
  .left1_ul{
    list-style: none;
  }
  #container{
    width: 500px;
    min-height: 200px;
    padding: 20px;
    position: relative; /*一定加上这句,否则连线位置发生错乱*/
  }

  .left1{
    float: left;
    width: 150px;
  }
  .right1{
    float: right;
    width: 150px;
  }

  .left1 li,.right1 li{
    width: 100%;
    border-radius: 4px;
    border: 1px solid #1e90ff;
    background: #70a1ff;
    margin-bottom: 20px;
    padding: 8px 5px;
    text-align: center;
    color: white;
    font-weight: bold;
  }
</style>

在父组件中引入使用

 

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐