<template>
<div class="box">
<div @click="clearLine">clear</div>
<div @click="initConponents">line</div>
<div @click="getData">get</div>
</div>
<div class="wrapper" ref="wrapper">
<div class="left_box com_box">
<div class="source_title com_title">{{ props.sourceTitle }}</div>
<div class="content_box" id="content_box1">
<div
class="item_box"
:id="item.id"
v-for="(item, index) in sourceList"
:key="`item-${index}`"
>
{{ item.name }}
</div>
</div>
</div>
<div class="right_box com_box">
<div class="target_title com_title">{{ props.targetTitle }}</div>
<div class="content_box" id="content_box2">
<div
class="item_box"
:id="item.id"
v-for="(item, index) in targetList"
:key="`item-${index}`"
>
{{ item.name }}
</div>
</div>
</div>
</div>
</template>
<script setup>
import { jsPlumb } from 'jsplumb'
const props = defineProps({
targetTitle: {
type: String,
default: '目标字段'
},
sourceTitle: {
type: String,
default: '源字段'
}
})
const wrapper = ref()
// 公共样式 点样式和连线样式
const commonData = {
isSource: true, // 是否允许被手动连线
isTarget: true, // 是否允许被手动连线
connectorStyle: { stroke: '#5085E2', strokeWidth: '2', dashstyle: '0' }, // 自定义连线时的颜色
connectorHoverStyle: {
lineWidth: 3,
strokeStyle: '#ff3040',
stroke: '#ff3040'
}, // 自定义线段连接后 鼠标经过的颜色 宽度
connectorOverlays: [['Arrow', { width: 10, length: 10, location: 1 }]], // 自定义连线时箭头的样式
connector: ['Bezier', { curviness: 50 }], // 连线样式
anchor: ['Left', 'Right'], // 点的位置
endpointStyle: { fill: '#5085E2', outlineWidth: 2 }, // 点的样式
endpointHoverStyle: { fill: '#ff3040', outlineWidth: 2 }, // 初始化连接时鼠标经过时点的样式
paintStyle: { stroke: '#5085E2', strokeWidth: 2 }, // 初始化连接时连线的颜色 宽度
hoverPaintStyle: { stroke: '#ff3040', strokeWidth: 2 }, // 初始化连接时鼠标经过时的连线颜色 宽度
overlays: [['Arrow', { width: 10, length: 10, location: 1 }]], // 初始化连接时箭头样式 location 0.5 箭头在中间 1在右侧
endpoint: [
'Dot',
{
radius: 5, // 圆的大小
fill: '#5085E2'
}
], // 端点样式设置
DragOptions: { cursor: 'crosshair' },
ConnectionsDetachable: false // 禁用拖到取消连线
}
const sourceList = ref([])
const targetList = ref([])
const initConponents = () => {
// 通过index (同行)
const source = sourceList.value.map((item) => item.id)
const target = targetList.value.map((item) => item.id)
// 通过uuid连接(自定义)
// const source = sourceList.value.map((item) => item.uuid)
// const target = targetList.value.map((item) => item.uuid)
source.forEach((item, index) => {
// 连线
jsPlumb.connect({ uuids: [item, target[index]] }, commonData)
})
}
const clearLine = () => {
const doms = document.querySelectorAll('.item_box')
doms.forEach((item) => {
// 根据id删除点的连线
jsPlumb.deleteConnectionsForElement(item.id)
})
}
const getData = () => {
// 获取全部连接线段的数据,通过id去list中查找,处理成接口想要的数据格式
console.log(jsPlumb.getAllConnections())
}
onMounted(() => {
jsPlumb.getInstance()
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list.forEach((item, index) => {
targetList.value.push({
name: `target-${item}`, // 展示字段
id: `target-${index}`, // id
uuid: `target-${item}` // 动态设置连接的id
})
sourceList.value.push({
name: `source-${item}`,
id: `source-${index}`,
uuid: `source-${item}`
})
})
nextTick(() => {
sourceList.value.forEach((item) => {
const dom = document.querySelector(`#${item.id}`)
// addEndpoint 添加右侧点位
jsPlumb.addEndpoint(
dom,
{
anchor: ['Right'],
uuid: item.id // 如果是同行连接 uuid: item.id 如果是uuid uuid: item.uuid 注意 需要和initConponents map条件一致
},
// 点的样式
{ ...commonData, maxConnections: 1 }
)
})
targetList.value.forEach((item) => {
const dom = document.querySelector(`#${item.id}`)
// addEndpoint 添加左侧点位
jsPlumb.addEndpoint(
dom,
{
anchor: ['Left'],
uuid: item.id // 如果是同行连接 uuid: item.id 如果是uuid uuid: item.uuid 注意 需要和initConponents map条件一致
},
// 点的样式
{ ...commonData, maxConnections: 1 }
)
})
})
// 添加单击连线事件
// jsPlumb.bind('click', function (conn) {
// // 删除线
// jsPlumb.deleteConnection(conn)
// })
// 鼠标经过线的样式
jsPlumb.bind('mouseover', function (conn) {
for (let i of document.querySelectorAll('.jtk-connector')) {
i.style.cursor = conn.targetId === 'r_dataDictionary' ? 'default' : 'pointer'
}
})
// 鼠标离开线的样式
jsPlumb.bind('mouseout', function (conn) {
for (let i of document.querySelectorAll('.jtk-connector')) {
i.style.cursor = conn.targetId === 'r_dataDictionary' ? 'default' : 'pointer'
}
})
// 连线之前,是否可连接检查
jsPlumb.bind('beforeDrop', function (info) {
// return false 不允许连接 true 允许连接
const sourceId = info.sourceId.split('-')[0]
const targetId = info.targetId.split('-')[0]
// 不允许连接同一侧的点 或者 不允许从右侧拉线到左侧 只能从左到右拉线
if (sourceId === targetId || sourceId.includes('target')) return false
return true
})
// 连线成功之后的回调
// jsPlumb.bind('connection', function (info) {
// console.log(info.connection, 9, info)
// })
})
</script>
<style lang="less" scoped>
.box {
display: flex;
width: 500px;
justify-content: space-between;
align-items: center;
margin: 50px auto;
}
.wrapper {
width: 1000px;
height: 500px;
margin: 200px auto 0;
display: flex;
align-items: center;
justify-content: space-between;
.com_box {
width: 30%;
height: 100%;
border: 1px solid #ccc;
display: flex;
flex-direction: column;
}
.com_title {
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
height: 30px;
line-height: 30px;
margin-bottom: 10px;
color: #fff;
background-color: #ccc;
}
.content_box {
height: 0;
flex: 1;
width: 100%;
overflow: auto;
display: flex;
flex-direction: column;
padding: 0 10px;
box-sizing: border-box;
> div {
height: 20px;
line-height: 19px;
border-bottom: 1px solid #ccc;
color: #ccc;
white-space: nowrap; /* 不换行 */
overflow: hidden; /* 超出部分不显示 */
text-overflow: ellipsis; /* 超出部分显示为... */
border: 1px solid #ccc;
border-bottom: none;
padding: 0 8px;
box-sizing: border-box;
&:last-child {
border-bottom: 1px solid #ccc;
}
}
}
}
</style>
标签:学习,const,uuid,连线,jsPlumb,item,vue3,id
From: https://www.cnblogs.com/demoTimes/p/17859999.html