JsPlumb社区版在Nuxt/Vue项目中无法动态添加节点和形状问题
解决方案
核心实现思路
动态创建jsPlumb节点只需三步操作:
- 点击按钮时创建对应样式的DOM节点,插入到jsPlumb绑定的容器中
- 调用jsPlumb实例的
manage方法,将DOM节点注册为可拖拽的jsPlumb节点 - 给节点添加连接端点,方便后续连线使用
完整修改后代码
<template> <div> <div class="container-fluid"> <div class="row"> <div class="col-md-6"> <button class="btn btn-primary btn-sm" @click="addConnector"> Add Connector </button> <button class="btn btn-primary btn-sm" @click="addNode"> Add Event </button> <button class="btn btn-success btn-sm" @click="submitEvents"> Submit </button> </div> </div> <div class="row"> <div class="col-md-12"> <div id="diagram" ref="diagram" style="position: relative; width:100%; height:800px;border:1px solid #eee;" /> </div> </div> </div> </div> </template> <script> let jsPlumb = null export default { data () { return { nodeCounter: 0, nodeArray: [], connectorCounter: 0, connectorArray: [], allEventsInfoArray: [] } }, async mounted () { if (process.browser) { const jsPlumbBrowserUI = await import('@jsplumb/browser-ui') jsPlumb = jsPlumbBrowserUI.newInstance({ dragOptions: { cursor: 'pointer', zIndex: 2000 }, container: this.$refs.diagram }) // 全局默认端点配置,避免每个节点重复写 jsPlumb.addEndpointSpec({ endpoint: 'Dot', anchor: 'AutoDefault', maxConnections: -1 // 不限制连接数 }) } }, methods: { addNode () { this.nodeCounter++ const nodeId = `node_${this.nodeCounter}` // 1. 创建节点DOM const nodeEl = document.createElement('div') nodeEl.id = nodeId nodeEl.className = 'flow-node' nodeEl.innerText = `节点${this.nodeCounter}` // 设置初始位置,每次新增偏移20px避免重叠 nodeEl.style.left = `${100 + this.nodeCounter * 20}px` nodeEl.style.top = `${100 + this.nodeCounter * 20}px` // 2. 插入到画布容器 this.$refs.diagram.appendChild(nodeEl) // 3. 注册为jsPlumb可拖拽节点 jsPlumb.manage(nodeEl) // 4. 给节点添加上下左右四个连接端点 ['Top', 'Right', 'Bottom', 'Left'].forEach(anchor => { jsPlumb.addEndpoint(nodeId, { anchor }) }) // 保存节点信息方便后续处理 this.nodeArray.push({ id: nodeId, el: nodeEl }) }, addConnector () { // connect方法必须指定source和target参数,示例默认连接最后两个节点,可按需改为选中节点再连线的逻辑 if (this.nodeArray.length < 2) return alert('至少需要2个节点才能创建连线') jsPlumb.connect({ source: this.nodeArray[this.nodeArray.length - 2].id, target: this.nodeArray[this.nodeArray.length - 1].id, anchor: 'AutoDefault', endpoints: ['Dot', 'Blank'], overlays: [ { type: 'Arrow', options: { location: 1 } }, { type: 'Label', options: { label: 'foo', location: 0.25, id: `label_${this.connectorCounter++}` } } ] }) }, submitEvents () { // 提交逻辑可自行获取jsPlumb实例的连接、节点信息 console.log('所有节点:', this.nodeArray) console.log('所有连线:', jsPlumb.getConnections()) } } } </script> <style scoped> .flow-node { position: absolute; width: 120px; height: 40px; line-height: 40px; text-align: center; border: 1px solid #2d8cf0; background: #e8f3ff; border-radius: 4px; cursor: move; } /* style加了scoped时需要用深度选择器覆盖jsPlumb默认样式 */ :deep(.jtk-endpoint) { width: 10px; height: 10px; background: #2d8cf0; } :deep(.jtk-connector) { stroke: #2d8cf0; stroke-width: 2; } </style>
注意事项
- 示例给diagram容器加了固定高度和边框,避免画布高度为0看不见节点,可按需调整
- 新增节点的初始位置是按序号偏移的,可改成固定位置或者鼠标点击位置生成
- addConnector方法默认连接最后两个节点,实际使用时可以改成用户点击选中两个节点再连线的逻辑
内容的提问来源于stack exchange,提问作者BATMAN_2008
相关产品推荐
相关产品推荐

