初识vue+jsplumb(第Demo,手动连线功能、删除连线以和保存功能)
成品图如下:
<template>
<div id="wrapper" >
<div class="line-wrap" style="margin-left: 70px;">
<!-- 循环渲染盒子 -->
<div :id="item" class="state-item" v-for="(item, index) in pointsList" :key="index" >{{item}}</div>
</div>
<el-button @click="saveLine">保存结果</el-button>
{{releationListStr}}
</div>
<!-- 在这里我们定义了基本的盒子,我们可以通过盒子的className定义盒子的样式,记得每个盒子一定要定义唯一的Id -->
</template>
<script>
import {jsPlumb} from 'jsplumb'
export default {
name: 'landing-page',
data() {
return {
jsplumbDemo: null,
pointsList: [],
releationList: [],
releationListStr: [],//存点击保存时的连线
jsPlumbConnectOptions: {
isSource: true,
isTarget: true,
anchor: ['Left', 'Right', 'Top', 'Bottom', [0.3, 0, 0, -1], [0.7, 0, 0, -1], [0.3, 1, 0, 1], [0.7, 1, 0, 1]],//定义可用连接点坐标,坐标位于盒子的四周
connector: ['StateMachine'],//连接线样式
endpoint: 'Blank',//端点样式
}
}
},
mounted () {
this.jsplumbDemo = jsPlumb.getInstance()
// 在这里我们实例了一个对象
// this.setLineList()
// this.doRepaintLine()
this.initData()
},
methods: {
initData() {//接受初始数据,可以通过axios去后端请求,这里我就不做请求了,写死端点列表与关系列表
this.pointsList = ['A', 'B', 'C', 'D']
this.releationList = [
{name: 'A', kindredList: ['B'], friendsList: ['D']},
{name: 'B', kindredList: ['C', 'D'], friendsList: []}
]
this.$nextTick(() => {//解释下为什么要用nextTick,因为需要先渲染出盒子,才能在盒子上进行赋端点,以及连线的操作,如果缺了nextTick那么会报盒子不存在
this.pointsList.forEach(i => {
this.makeTopoNodeDrag(i)//设置可拖动拓扑节点
this.addEndPoints(i)//设置盒子可连线的端点位置已经连线样式以及启用一些监听
})
if(this.releationList && this.releationList.length) {
this.doRepaintLine() //从后端获取到关系表后,可以渲染初始的一些连线
}
})
},
makeTopoNodeDrag(eleId) {//设置可拖动拓扑节点
this.jsplumbDemo.draggable(eleId, {containment: 'parent'});
},
addEndPoints(eleId) {//设置盒子可连线的端点位置已经连线样式
let style = {
endpoint: 'Dot',
// 将isSource和isTarget设置为true,可以在拖动时自动创建连接
isSource: true,
isTarget: true,
connector: ['StateMachine'],
// 默认情况下,maxConnections为1,表示一个端点只能有一条连线。设置为-1,不限制连线数量
maxConnections: -1,
// 端点样式
paintStyle: {fill: 'rgba(54,54,54,0)', },
// 鼠标悬浮端点样式
hoverPaintStyle: {fill: 'rgba(64,54,54,0.5)',},
// 拖拽连线样式
connectorStyle: {stroke: 'rgba(54, 61, 63, 0.5)', strokeWidth: 3, },
connectorHoverStyle: { stroke: 'rgba(54, 61, 63, 0.5)', strokeWidth: 5,},
// 设置箭头
connectorOverlays: [['Arrow', { width: 10, location: 1, id: 'arrow' }]],
}
this.jsplumbDemo.addEndpoint( eleId, {anchor: ['Left', 'Right', 'Top', 'Bottom', [0.3, 0, 0, -1], [0.7, 0, 0, -1], [0.3, 1, 0, 1], [0.7, 1, 0, 1]]}, style)
this.jsplumbDemo.bind('beforeDrop', info => {//监听连线
// 禁止在同一端点上连接
if(info.sourceId === info.targetId) {
return false; // return false连接不会建立,必须为false
}
// 可以在连接前再添加判断条件,例如一个节点上的同一个端点只能连接一次等等。。省略代码
return true; // 连接自动建立
})
this.jsplumbDemo.bind('contextmenu', info => {//允许右键删除该条连线,也可以自定义键盘删除(设置监听连线选中状态,并高亮,然后监听键盘的按下弹起,触发删除连线的方法)
let lineInfo = info;
this.jsplumbDemo.deleteConnection(lineInfo);
})
},
setLineList() {
let lineList = [] // 定义一个空列表用来存连线
this.releationList.forEach(i =>{
i.kindredList.forEach(j => {
let storeInfo = {
source: i.name,//起点Id
target: j,//终点Id
overlays: [["Arrow", { width: 10, length: 10, location: 1 }]],//定义连接线部件的样式
paintStyle: { stroke: '#66ccff', strokeWidth: 2 },//定义连接线的颜色以及粗细,这里我们定义亲属的连接线为蓝色
}
lineList.push(storeInfo)
})// 循环亲属关系列表,起点以name作为起点,终点以亲属的名字
i.friendsList.forEach(j => {
let storeInfo = {
source: i.name,
target: j,
overlays: [["Arrow", { width: 10, length: 10, location: 0.5 }]],
paintStyle: { stroke: '#99ff99', strokeWidth: 2 },//这里我们定义朋友之间的连线用绿色
}// 循环亲属关系列表,起点以name作为起点,终点以朋友的名字
lineList.push(storeInfo)
})
})
return lineList
},
doRepaintLine() {
let that = this
let lineList = this.setLineList()
this.jsplumbDemo.ready(function () {
lineList.forEach((item) => {
that.jsplumbDemo.connect(item, that.jsPlumbConnectOptions);
});
})
},
saveLine() {
console.log(this.jsplumbDemo.getConnections());
let lineList = this.jsplumbDemo.getConnections()
let blankList = []
lineList.forEach(i => {
let storeInfo = {
source: i.sourceId,
target: i.targetId
}
blankList.push(storeInfo)
})
this.releationListStr = blankList //会输出一个sorce,target列表,可以通过axios请求存到后端
},
},
}
</script>
<style >
#wrapper {
background:
radial-gradient(
ellipse at top left,
rgba(255, 255, 255, 1) 40%,
rgba(229, 229, 229, .9) 100%
);
height: 100vh;
padding: 60px 80px;
width: 100vw;
}
.state-item {
width: 80px;
height: 40px;
color: #606266;
background: #f6f6f6;
border: 2px solid rgba(0, 0, 0, 0.05);
text-align: center;
line-height: 40px;
font-family: sans-serif;
border-radius: 4px;
margin-right: 60px;
}
.line-wrap {
display: flex;
margin-bottom: 40px;
}
</style>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhicgejg
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
excel图片置于文字下方的方法
PHP中文网 06-27 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
微信提示登录环境异常是什么意思原因
PHP中文网 04-09 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22 -
微信人名旁边有个图标有什么用
PHP中文网 03-11