Jsplumb + vue2
时间: 2023-10-05 20:11:02 浏览: 124
Jsplumb是一个基于JavaScript的流程图库,可以用来创建和编辑连线、节点等元素。Vue2是一个流行的JavaScript框架,用于构建用户界面。
在Vue2中使用Jsplumb,你需要先安装依赖,可以使用npm命令进行安装。具体的安装步骤如下:
1. 打开终端,进入项目的根目录
2. 运行命令 `npm install` 安装所有的依赖项
3. 运行命令 `npm run dev` 启动开发服务器,该服务器会在本地的8080端口上运行,支持热重载
4. 如果你想构建生产环境的版本,可以运行命令 `npm run build`,它会生成一个带有代码压缩的生产版本
注意,使用Jsplumb和Vue2构建项目时,你可能还需要阅读README.md文件,其中可能包含了一些重要的配置或使用说明。请确保按照README.md的指示进行操作。
希望以上信息能够帮助你理解如何在Vue2中使用Jsplumb。如果还有其他问题,请随时提问。
相关问题
jsplumb+dragable+vue3 实现可拖拽的流程编辑
好的,以下是一个使用jsplumb+dragable+vue3实现可拖拽的流程编辑器的完整例子:
```vue
<template>
<div class="container" ref="container">
<div class="node" v-for="node in nodes" :key="node.id" :style="{ left: node.x + 'px', top: node.y + 'px' }" :data-id="node.id" v-draggable>
<div class="title">{{ node.title }}</div>
<div class="content">{{ node.content }}</div>
<div class="endpoint" :class="'endpoint-' + index" v-for="(endpoint, index) in node.endpoints" :key="index" :data-id="node.id + '-' + index"></div>
</div>
</div>
</template>
<script>
import { onMounted, ref } from 'vue';
import jsPlumb from 'jsplumb';
import 'jsplumb/dist/js/jsplumb.min.css';
import 'dragula/dist/dragula.min.css';
import dragula from 'dragula';
export default {
name: 'DraggableFlowchart',
setup() {
const container = ref(null);
const nodes = ref([
{
id: 'node1',
title: 'Node 1',
content: 'This is Node 1',
x: 100,
y: 100,
endpoints: [
['Right', { uuid: 'node1-right' }],
['Bottom', { uuid: 'node1-bottom' }],
],
},
{
id: 'node2',
title: 'Node 2',
content: 'This is Node 2',
x: 300,
y: 100,
endpoints: [
['Left', { uuid: 'node2-left' }],
['Bottom', { uuid: 'node2-bottom' }],
],
},
]);
onMounted(() => {
const instance = jsPlumb.getInstance({
// 设置连接线的样式
PaintStyle: {
strokeWidth: 2,
stroke: '#61B7CF',
},
// 鼠标悬停在连接线上的样式
HoverPaintStyle: {
strokeWidth: 3,
stroke: '#216477',
},
// 端点的样式设置
EndpointStyles: [
{ fill: '#61B7CF' },
{ fill: '#216477' },
],
// 鼠标悬停在端点上的样式
EndpointHoverStyles: [
{ fill: '#216477' },
{ fill: '#61B7CF' },
],
// 连接线的锚点,可以设置为不同的位置,例如左侧、右侧、中心等位置
Anchors: ['Right', 'Left', 'Top', 'Bottom'],
// 设置连接线的类型,可以设置为Bezier、Straight等类型
Connector: ['Bezier', { curviness: 150 }],
Container: container.value,
});
// 添加节点和端点
nodes.value.forEach((node) => {
instance.draggable(node.id);
node.endpoints.forEach((endpoint, index) => {
instance.addEndpoint(node.id, {
anchor: endpoint[0],
uuid: endpoint[1].uuid,
});
});
});
// 连接两个端点
instance.connect({
uuids: ['node1-right', 'node2-left'],
});
// 监听连接事件
instance.bind('connection', (info) => {
console.log(`Connection established: ${info.sourceId} -> ${info.targetId}`);
});
// 监听断开连接事件
instance.bind('connectionDetached', (info) => {
console.log(`Connection detached: ${info.sourceId} -> ${info.targetId}`);
});
// 监听删除连接事件
instance.bind('connectionDeleted', (info) => {
console.log(`Connection deleted: ${info.sourceId} -> ${info.targetId}`);
});
// 监听节点位置改变事件
instance.bind('drag', (info) => {
const node = nodes.value.find((n) => n.id === info.el.getAttribute('data-id'));
node.x = info.pos[0];
node.y = info.pos[1];
});
// 使用dragula库实现节点拖拽排序
const drake = dragula([container.value], {
moves(el, container, handle) {
return handle.classList.contains('title');
},
});
// 监听节点排序事件
drake.on('drop', () => {
console.log('Node order changed');
});
});
return {
container,
nodes,
};
},
};
</script>
<style>
.container {
width: 100%;
height: 100%;
position: absolute;
}
.node {
position: absolute;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
cursor: move;
}
.title {
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
}
.content {
font-size: 14px;
margin-bottom: 10px;
}
.endpoint {
width: 10px;
height: 10px;
background-color: #61B7CF;
border-radius: 50%;
position: absolute;
}
.endpoint-0 {
right: -5px;
top: 50%;
transform: translateY(-50%);
}
.endpoint-1 {
left: -5px;
top: 50%;
transform: translateY(-50%);
}
.endpoint-2 {
right: 50%;
top: -5px;
transform: translateX(50%);
}
.endpoint-3 {
right: 50%;
bottom: -5px;
transform: translateX(50%);
}
</style>
```
在这个例子中,我们首先引入了`jsPlumb`和`dragula`库,并使用`onMounted`钩子来初始化一个`jsPlumb`实例和一个`dragula`实例。在实例化过程中,我们设置了连接线的样式、锚点、连接线类型等参数,然后添加了两个节点和它们的端点,并连接了这两个节点的端点。我们还为节点添加了拖拽和排序的功能,并且监听了连接、断开连接、删除连接和位置改变事件。
请注意,这只是一个简单的例子,仅用于演示如何使用`jsPlumb`和`dragula`实现可拖拽的流程编辑器。实际应用中,您可能需要更复杂的逻辑和交互来处理不同的情况。
vite+elementPlus+vue3+jsplumb+pinia+sortable实现完整的流程图
实现完整的流程图需要以下步骤:
1. 安装依赖
```
npm install vite vue@next element-plus @vueuse/core jsplumb pinia sortablejs
```
2. 创建组件
在src/components目录下创建FlowChart.vue组件:
```html
<template>
<div class="flow-chart">
<div class="chart-container">
<div class="chart"></div>
</div>
</div>
</template>
<script>
import { defineComponent, ref, watchEffect } from 'vue'
import { useRoute } from 'vue-router'
import { useStore } from 'pinia'
import Sortable from 'sortablejs'
import jsPlumb from 'jsplumb'
import 'jsplumb/dist/js/jsplumb.min.css'
export default defineComponent({
name: 'FlowChart',
setup() {
const store = useStore()
const route = useRoute()
const chartInstance = ref(null)
watchEffect(() => {
drawChart()
})
function drawChart() {
const chart = document.querySelector('.chart')
chart.innerHTML = ''
const nodes = store.state.nodes.filter(
(node) => node.page === route.name
)
const instance = jsPlumb.getInstance({
Container: chart,
Connector: ['Straight', { gap: 5 }],
Endpoint: ['Dot', { radius: 4 }],
EndpointStyle: { fill: 'transparent', stroke: '#555' },
PaintStyle: { stroke: '#555', strokeWidth: 2 },
DragOptions: { cursor: 'pointer', zIndex: 2000 },
ConnectionOverlays: [
[
'Arrow',
{
location: 1,
visible: true,
width: 11,
length: 11,
id: 'ARROW',
},
],
],
})
nodes.forEach((node) => {
const el = document.createElement('div')
el.classList.add('node')
el.setAttribute('id', node.id)
el.style.top = node.top + 'px'
el.style.left = node.left + 'px'
el.innerHTML = node.label
chart.appendChild(el)
instance.draggable(el, {
stop: (event) => {
const top = parseInt(event.el.style.top)
const left = parseInt(event.el.style.left)
store.updateNode(node.id, { top, left })
},
})
})
nodes.forEach((node) => {
const connections = store.state.connections.filter(
(conn) => conn.source === node.id
)
connections.forEach((conn) => {
instance.connect({
source: node.id,
target: conn.target,
overlays: [['Arrow', { location: 1, width: 11, length: 11 }]],
})
})
})
chartInstance.value = instance
}
return {
chartInstance,
}
},
})
</script>
<style scoped>
.flow-chart {
width: 100%;
height: 100%;
}
.chart-container {
position: relative;
width: 100%;
height: 100%;
overflow: auto;
}
.chart {
position: absolute;
top: 0;
left: 0;
width: 10000px;
height: 10000px;
}
.node {
position: absolute;
width: 100px;
height: 40px;
background-color: #fff;
border: 1px solid #ccc;
text-align: center;
line-height: 40px;
cursor: pointer;
}
</style>
```
3. 创建路由
在src/router/index.js中添加路由:
```js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import FlowChart from '../components/FlowChart.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/flow-chart',
name: 'FlowChart',
component: FlowChart,
},
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
})
export default router
```
4. 创建状态管理
在src/store/index.js中创建状态管理:
```js
import { defineStore } from 'pinia'
export const useFlowChartStore = defineStore('flow-chart', {
state: () => ({
nodes: [],
connections: [],
}),
actions: {
addNode(node) {
node.id = Date.now().toString()
node.top = 100
node.left = 100
this.nodes.push(node)
},
updateNode(nodeId, data) {
const node = this.nodes.find((node) => node.id === nodeId)
if (node) {
Object.assign(node, data)
}
},
addConnection(connection) {
this.connections.push(connection)
},
removeNode(nodeId) {
this.nodes = this.nodes.filter((node) => node.id !== nodeId)
this.connections = this.connections.filter(
(conn) => conn.source !== nodeId && conn.target !== nodeId
)
},
removeConnection(connection) {
this.connections = this.connections.filter(
(conn) =>
conn.source !== connection.source || conn.target !== connection.target
)
},
},
})
```
5. 创建视图
在src/views/Home.vue中创建视图:
```html
<template>
<div class="home">
<div class="sidebar">
<form @submit.prevent="addNode">
<label>
Label:
<input type="text" v-model="label" />
</label>
<button>Add Node</button>
</form>
<ul>
<li v-for="node in nodes" :key="node.type">
{{ node.label }}
<button @click="removeNode(node.id)">Remove</button>
</li>
</ul>
</div>
<div class="main">
<router-view />
</div>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue'
import { useFlowChartStore } from '../store'
export default defineComponent({
name: 'Home',
setup() {
const store = useFlowChartStore()
const label = ref('')
const nodes = ref([
{ type: 'start', label: 'Start' },
{ type: 'end', label: 'End' },
{ type: 'task', label: 'Task' },
{ type: 'decision', label: 'Decision' },
])
function addNode() {
store.addNode({ type: 'task', label: label.value })
label.value = ''
}
function removeNode(nodeId) {
store.removeNode(nodeId)
}
return {
label,
nodes,
addNode,
removeNode,
}
},
})
</script>
<style scoped>
.home {
display: flex;
flex-direction: row;
height: 100%;
}
.sidebar {
width: 200px;
padding: 20px;
background-color: #f5f5f5;
}
.main {
flex: 1;
height: 100%;
}
</style>
```
6. 运行应用
在package.json中添加运行命令:
```json
{
"scripts": {
"dev": "vite"
}
}
```
运行应用:
```
npm run dev
```
应用运行后,打开http://localhost:3000/,就可以看到一个空的流程图页面。在侧边栏添加节点,然后拖动节点到画布中,连接节点,就可以完成一个简单的流程图。
阅读全文