在 vue 中使用 jsPlumb 总结
# 1、安装
npm install jsplumb --save
1
# 2、在main.js中引入
在这里直接放进了vue原型中,方便下面页面使用
import jsPlumb from 'jsplumb'
Vue.prototype.$jsPlumb = jsPlumb.jsPlumb
1
2
2
# 初始化jsPlumb实例
对于jsPlumb
的操作都变为对实例对象的操作。初始化我放在created
生命周期中,其他操作都放在mounted
中,因为jsPlumb
插件一定要在页面加载完成后才能起作用。
created(){
this.jsPlumb = this.$jsPlumb.getInstance({
Container:"workspace", //选择器id
EndpointStyle: { radius: 4, fill: "#acd"}, //端点样式
PaintStyle: { stroke: '#fafafa',strokeWidth:3},// 绘画样式,默认8px线宽 #456
HoverPaintStyle: { stroke: '#1E90FF' }, // 默认悬停样式 默认为null
EndpointHoverStyle: { fill: '#F00', radius:6 }, // 端点悬停样式
ConnectionOverlays:[ //连线上的默认样式 这里是箭头
["Arrow",{
location:1,
paintStyle: {
stroke: '#00688B',
fill: '#00688B',
}
}]
],
Connector:["Straight",{gap:1}] //要使用的默认连接器的类型:折线,流程等
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这里需要注意一点,放流程图的容器得设置成 relative
c定位的,因为连线都是绝对定位的。
# 元素拖动
在实例对象上用draggable方法
this.jsPlumb.draggable("elementId");
1
对区域内元素设置可拖动
this.jsPlumb.draggable("someElement", {
containment:true
});
1
2
3
2
3
# 节点连线
let params = {
source: node.sourceId,
target: node.targetId
};
let setting = {
// 为自定义的jsPlumb设置,也可以不传入
}
this.jspInit.connect(params,setting);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 节点的连线与拖拽切换
function toggleDraggable(flowMenuObj) {
if (type === "connection") {
this.cursor = "crosshair";
this.nodes.forEach((node, index) => {
let f = this.jspInit.toggleDraggable(node.id);
if (f) {
this.jspInit.toggleDraggable(node.id);
}
let config = { ...jsPlumbConfig, ...{ anchor: flowAnchor } };
this.jspInit.unmakeSource(node.id);
this.jspInit.unmakeTarget(node.id);
this.connector = flowMenuObj.connector;
config.connector = [this.connector];
this.jspInit.makeSource(node.id, config);
this.jspInit.makeTarget(node.id, config);
});
} else if (type === "move") {
this.cursor = "move";
this.nodes.forEach((node, index) => {
let f = this.jspInit.toggleDraggable(node.id);
if (!f) {
this.jspInit.toggleDraggable(node.id);
}
this.jspInit.unmakeSource(node.id);
this.jspInit.unmakeTarget(node.id);
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
基础案例:
<template>
<div>
<div id="container">
<div class="col1">
<div v-for="item in list1" :id="item.nodeId" name="cell">{{item.name}}</div>
</div>
<div class="col2">
<div v-for="item in list2" :id="item.nodeId" name="cell">{{item.name}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
jsPlumb: null,
list1:[{name:'XX',nodeId:'x'},{name:'YY',nodeId:'y'},{name:'ZZ',nodeId:'z'}],
list2:[{name:'AA',nodeId:'a'},{name:'BB',nodeId:'b'},{name:'CC',nodeId:'c'}],
connlist:[{sourceNodeId:'x',targetNodeId:'a'},{sourceNodeId:'y',targetNodeId:'b'},{sourceNodeId:'z',targetNodeId:'c'}]
}
},
created() {
this.jsPlumb = this.$jsPlumb.getInstance({
Container:"container", //选择器id
EndpointStyle: { radius: 4, fill: "#acd"}, //端点样式
PaintStyle: { stroke: '#fafafa',strokeWidth:4},// 绘画样式,默认8px线宽 #456
HoverPaintStyle: { stroke: '#1E90FF' }, // 默认悬停样式 默认为null
EndpointHoverStyle: { fill: '#F00', radius:6 }, // 端点悬停样式
ConnectionOverlays:[
["Arrow",{
location:1,
paintStyle: {
stroke: '#00688B',
fill: '#00688B',
}
}]
],
Connector:["Straight",{gap:1}], //要使用的默认连接器的类型:折线,流程等
DrapOptions:{cursor:"crosshair",zIndex:2000}
});
},
mounted() {
let ins = this.jsPlumb,
allConnection = ins.getAllConnections();
ins.batch(() => {
this.initAll();
this.connectionAll();
});
this.switchContainer(true,true,false);
},
methods:{
initAll () {
let rl = this.list1;
for (let i = 0; i < rl.length; i++) {
this.init(rl[i].nodeId)
}
let rl2 = this.list2;
for (let i = 0; i < rl2.length; i++) {
this.init(rl2[i].nodeId)
}
},
// 初始化规则使其可以连线、拖拽
init (id) {
let ins = this.jsPlumb,
elem = document.getElementById(id);
ins.makeSource(elem,{
anchor: ["Perimeter", {anchorCount:200, shape:"Rectangle"}],
allowLoopback: false,
maxConnections: 1
});
ins.makeTarget(elem,{
anchor: ["Perimeter", {anchorCount:200, shape:"Rectangle"}],
allowLoopback: false,
maxConnections: 1
});
ins.draggable(elem,{
containment: true
});
},
connectionAll () {
let ins = this.jsPlumb;
ins.ready(() => {
for (let i = 0; i < this.connlist.length; i++) {
let conn = this.connlist[i],
connection = ins.connect({
source:conn.sourceNodeId,
target:conn.targetNodeId
});
connection.setPaintStyle({stroke:"#fafafa",strokeWidth:4})
}
})
},
switchContainer (target,source,draggable) {
let elem = document.getElementsByName("cell"),
ins = this.jsPlumb;
ins.setSourceEnabled(elem,source);
ins.setTargetEnabled(elem,target);
ins.setDraggable(elem,draggable);
},
}
}
</script>
<style>
#container{
margin: 50px;
position: relative;
background: #efefef;
width: 400px;
height: 400px;
}
.col2,.col1{
float: left;
}
.col1{
margin-left: 40px;
}
.col2{
margin-left: 150px;
}
#container>div>div{
width: 100px;
height: 40px;
line-height: 40px;
background: lightcyan;
margin-top: 40px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
jsPlumb 中还有 beforeDrop
,connection
,connectionDetached
,connectionMoved
等几个事件,分别在连线或点击前后触发,如果要保存连线修改的信息,可以在mounted中对实例化对象绑定事件,写法例如:
jsPlumb.bind('connect',(info) =>{
console.log(info)
// info 中包含connection,sourceId ,targetId 等值
})
1
2
3
4
2
3
4
# 参考资料
上次更新: 2024/01/30, 00:35:17
- 01
- Node与GLIBC_2.27不兼容解决方案08-19
- 02
- Git清空本地文件跟踪缓存08-13