vue实现拖拽连线
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:

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)






