如何基于@jsplumb/browser-ui在Nuxt.js/Vue.js应用中实现运行时动态创建节点
解决Nuxt.js/Vue.js中@jsplumb/browser-ui动态创建可拖拽节点的问题
我帮你完善了代码,实现点击「Add Event」按钮动态生成可拖拽的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 root"> <div class="col-md-12 body"> <div id="diagram" ref="diagram" class="diagram" style="position: relative; width:100%; height:100%;" /> </div> </div> </div> </div> </template> <script> export default { data () { return { nodeCounter: 0, nodeArray: [], connectorCounter: 0, connectorArray: [], allEventsInfoArray: [], jsPlumbInstance: null // 保存jsPlumb实例,方便methods调用 } }, async mounted () { const vm = this if (process.browser) { const JSPlumb = await require('@jsplumb/browser-ui') JSPlumb.ready(function () { const instance = JSPlumb.newInstance({ container: vm.$refs.diagram, // 预配置默认端点和连接线样式,方便后续连接功能 endpoint: "Dot", paintStyle: { fill: '#2ECC71', radius: 6 }, connectorStyle: { stroke: '#3498DB', strokeWidth: 2 } }) vm.jsPlumbInstance = instance // 将实例存入组件数据,供方法调用 console.log('jsPlumb实例已初始化:', instance) }) } }, methods: { addNode () { if (!this.jsPlumbInstance) return // 确保实例已完成初始化 this.nodeCounter++ const nodeId = `node_${this.nodeCounter}` // 1. 创建节点DOM元素 const nodeElement = document.createElement('div') nodeElement.id = nodeId nodeElement.className = 'jsplumb-node' nodeElement.textContent = `Event ${this.nodeCounter}` // 设置初始位置,避免节点重叠 nodeElement.style.left = `${100 + this.nodeCounter * 50}px` nodeElement.style.top = `${100 + this.nodeCounter * 50}px` // 2. 将节点添加到画布容器中 this.$refs.diagram.appendChild(nodeElement) // 3. 启用节点拖拽功能 this.jsPlumbInstance.makeDraggable(nodeElement, { containment: true, // 限制拖拽范围在画布内 grid: [20, 20] // 可选:开启网格对齐,让拖拽更规整 }) // 4. 为节点添加连接端点(可选,若需要后续的连接器功能) this.jsPlumbInstance.addEndpoint(nodeElement, { anchors: ['Right', 'Left'] // 左右各一个端点,方便节点间连接 }) // 5. 记录节点信息,方便后续提交或操作 this.nodeArray.push({ id: nodeId, position: { left: nodeElement.style.left, top: nodeElement.style.top }, label: `Event ${this.nodeCounter}` }) }, addConnector () { // 这里可以后续实现节点连接逻辑,比如获取选中的两个节点后调用connect方法 console.log('节点连接功能可在此处扩展') }, submitEvents () { // 提交时可收集所有节点和连接信息 console.log('所有事件信息:', { nodes: this.nodeArray, connectors: this.connectorArray }) } } } </script> <style scoped> .root { --bg-color: #fff; --line-color-1: #D5D8DC; --line-color-2: #a9a9a9; } .body { height: 100vh; margin: 0; } .diagram { height: 100%; background-color: var(--bg-color); background-image: conic-gradient(at calc(100% - 2px) calc(100% - 2px),var(--line-color-1) 270deg, #0000 0), conic-gradient(at calc(100% - 1px) calc(100% - 1px),var(--line-color-2) 270deg, #0000 0); background-size: 100px 100px, 20px 20px; } /* 自定义动态节点的样式 */ .jsplumb-node { position: absolute; padding: 10px 20px; background: #fff; border: 2px solid #3498DB; border-radius: 8px; cursor: move; box-shadow: 0 2px 4px rgba(0,0,0,0.1); user-select: none; } </style>
核心修改说明:
- 保存jsPlumb实例:在组件
data中新增变量存储实例,解决了原代码中实例无法被addNode方法访问的问题 - 动态生成节点DOM:通过原生DOM API创建节点元素,设置唯一ID、样式和初始位置后添加到画布
- 启用拖拽能力:调用jsPlumb的
makeDraggable方法,配置拖拽范围和网格对齐规则 - 添加连接端点:可选的端点配置为后续实现节点间连接功能打下基础
- 节点样式优化:新增
.jsplumb-node类,让动态生成的节点视觉上更清晰易识别
现在点击「Add Event」按钮就能生成可拖拽的节点,你可以根据需求调整节点样式、端点位置或拖拽行为。
内容的提问来源于stack exchange,提问作者BATMAN_2008
相关产品推荐
相关产品推荐

