当前位置:首页 > VUE

vue实现拖拽连线

2026-03-08 12:11:33VUE

Vue 实现拖拽连线

使用 vue-draggable 和 vue-connection-line

安装依赖库:

npm install vue-draggable vue-connection-line

在 Vue 组件中引入:

import Draggable from 'vuedraggable'
import VueConnectionLine from 'vue-connection-line'

模板部分实现拖拽元素和连线:

<template>
  <div>
    <draggable v-model="nodes" @end="onDragEnd">
      <div v-for="node in nodes" :key="node.id" class="node">
        {{ node.name }}
      </div>
    </draggable>

    <vue-connection-line 
      :connections="connections"
      :elements="nodes"
      element-id="id"
    />
  </div>
</template>

脚本部分定义数据和连接关系:

export default {
  components: { Draggable, VueConnectionLine },
  data() {
    return {
      nodes: [
        { id: 1, name: 'Node 1', x: 50, y: 50 },
        { id: 2, name: 'Node 2', x: 200, y: 200 }
      ],
      connections: [
        { from: 1, to: 2 }
      ]
    }
  },
  methods: {
    onDragEnd() {
      // 拖拽结束处理逻辑
    }
  }
}

自定义实现方案

创建可拖拽节点组件:

Vue.component('drag-node', {
  template: `
    <div class="node" 
         draggable="true"
         @dragstart="dragStart"
         @dragend="dragEnd">
      <slot></slot>
    </div>
  `,
  methods: {
    dragStart(e) {
      e.dataTransfer.setData('nodeId', this.$vnode.key)
    },
    dragEnd() {
      // 处理拖拽结束
    }
  }
})

实现画线功能:

function drawLine(fromEl, toEl) {
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
  const line = document.createElementNS('http://www.w3.org/2000/svg', 'line')

  const fromRect = fromEl.getBoundingClientRect()
  const toRect = toEl.getBoundingClientRect()

  line.setAttribute('x1', fromRect.left + fromRect.width/2)
  line.setAttribute('y1', fromRect.top + fromRect.height/2)
  line.setAttribute('x2', toRect.left + toRect.width/2)
  line.setAttribute('y2', toRect.top + toRect.height/2)
  line.setAttribute('stroke', 'black')

  svg.appendChild(line)
  document.body.appendChild(svg)
}

使用第三方库 jsplumb

安装 jsplumb:

npm install jsplumb

在 Vue 中使用:

import { jsPlumb } from 'jsplumb'

export default {
  mounted() {
    this.initJsPlumb()
  },
  methods: {
    initJsPlumb() {
      jsPlumb.ready(() => {
        jsPlumb.connect({
          source: 'node1',
          target: 'node2',
          anchors: ['Right', 'Left'],
          connector: ['Straight']
        })
      })
    }
  }
}

性能优化建议

批量更新节点位置时使用 requestAnimationFrame:

function updateNodePositions() {
  requestAnimationFrame(() => {
    // 更新节点位置逻辑
  })
}

对于复杂场景考虑使用 WebGL 渲染库如 PIXI.js:

vue实现拖拽连线

import * as PIXI from 'pixi.js'

const app = new PIXI.Application()
document.body.appendChild(app.view)

const graphics = new PIXI.Graphics()
app.stage.addChild(graphics)

// 绘制连线
graphics.lineStyle(2, 0x000000)
graphics.moveTo(x1, y1)
graphics.lineTo(x2, y2)

标签: 拖拽vue
分享给朋友:

相关文章

vue SSG实现

vue SSG实现

Vue SSG 实现方法 Vue 的静态站点生成(SSG)可以通过多种工具和框架实现,以下是几种常见的方法: 使用 VuePress VuePress 是一个基于 Vue 的静态站点生成器,适合文档…

vue实现剪辑

vue实现剪辑

Vue 实现视频剪辑功能 在Vue中实现视频剪辑功能通常需要结合HTML5的<video>元素和第三方库(如FFmpeg.js或Video.js)。以下是几种常见的实现方法: 使用FFm…

vue实现erp

vue实现erp

Vue实现ERP系统的关键步骤 技术选型与架构设计 采用Vue 3 + TypeScript构建前端,搭配Pinia状态管理,Element Plus或Ant Design Vue作为UI框架。后端可…

vue实现图片

vue实现图片

Vue 实现图片功能的方法 静态图片引入 在 Vue 项目中,可以通过 src 属性直接引入静态图片。图片通常放在 public 或 assets 目录下。 <template> &…

vue compile 实现

vue compile 实现

Vue 编译实现原理 Vue 的编译过程将模板字符串转换为渲染函数,主要分为解析、优化和代码生成三个阶段。 解析阶段(Parse) 将模板字符串转换为抽象语法树(AST)。Vue 使用正则表达式和有…

vue实现定时

vue实现定时

Vue 实现定时功能的方法 使用 setInterval 和 clearInterval 在 Vue 中可以通过 setInterval 和 clearInterval 实现定时功能。在组件的 mou…