最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
vue+jsplumb实现工作流程图代码示例
时间:2022-06-29 01:49:35 编辑:袖梨 来源:一聚教程网
本篇文章小编给大家分享一下vue+jsplumb实现工作流程图代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
先写一个demo,大概样子如下:
官网文档Home | jsPlumb Toolkit Documentation
先安装插件
npm install jsplumb --save
安装panzoom,主要用于鼠标滚轮缩放流程图
npm install panzoom --save
在需要的页面引入插件
import panzoom from 'panzoom'
import { jsPlumb } from 'jsplumb'
接下来先写布局
父组件
flowNode是子组件
{{ node.nodeName }}
样式主要是子组件的,父组件样式随意就行
css;">
页面样式写完,接下来写插件配置
jsPlumb.ready() 是一个钩子函数,它会在 jsPlumb 准备完毕时执行。
连接线的建立是通过 jsPlumb.connect() 方法实现的。该方法接受一个对象作为配置项。其中包含了与上述概念一一对应的配置项,以及一些额外的样式。
source: 源对象,可以是对象的 id 属性、Element 对象或者 Endpoint 对象。
target: 目标对象,可以是对象的 id 属性、Element 对象或者 Endpoint 对象。
anchor: 是一个数组,数组中每一项定义一个锚点。
初始化方法
init() {
this.jsPlumb.ready(() => {
// 导入默认配置
this.jsPlumb.importDefaults(this.jsplumbSetting)
// 完成连线前的校验
this.jsPlumb.bind('beforeDrop', evt => {
const res = () => { } // 此处可以添加是否创建连接的校验, 返回 false 则不添加;
return res
})
this.loadEasyFlow()
// 会使整个jsPlumb立即重绘。
this.jsPlumb.setSuspendDrawing(false, true)
})
this.initPanZoom()
},
// 加载流程图
loadEasyFlow() {
// 初始化节点
for (let i = 0; i
this.data 是需要渲染的数据,放在文章末尾,具体数据按照接口实际返回的来写
this.jsplumbSourceOptions 是jsplumb配置信息,新建一个文件编写,具体如下:
export const jsplumbSetting = {
grid: [10, 10],
// 动态锚点、位置自适应
anchor: ['TopCenter', 'RightMiddle', 'BottomCenter', 'LeftMiddle'],
Container: 'flow',
// 连线的样式 StateMachine、Flowchart,有四种默认类型:Bezier(贝塞尔曲线),Straight(直线),Flowchart(流程图),State machine(状态机)
Connector: ['Flowchart', { cornerRadius: 5, alwaysRespectStubs: true, stub: 5 }],
// 鼠标不能拖动删除线
ConnectionsDetachable: false,
// 删除线的时候节点不删除
DeleteEndpointsOnDetach: false,
// 连线的端点
// Endpoint: ["Dot", {radius: 5}],
Endpoint: [
'Rectangle',
{
height: 10,
width: 10
}
],
// 线端点的样式
EndpointStyle: {
fill: 'rgba(255,255,255,0)',
outlineWidth: 1
},
LogEnabled: false, // 是否打开jsPlumb的内部日志记录
// 绘制线
PaintStyle: {
stroke: '#409eff',
strokeWidth: 2
},
HoverPaintStyle: { stroke: '#409eff' },
// 绘制箭头
Overlays: [
[
'Arrow',
{
width: 8,
length: 8,
location: 1
}
]
],
RenderMode: 'svg'
}
// jsplumb连接参数
export const jsplumbConnectOptions = {
isSource: true,
isTarget: true,
// 动态锚点、提供了4个方向 Continuous、AutoDefault
anchor: ['TopCenter', 'RightMiddle', 'BottomCenter', 'LeftMiddle']
}
export const jsplumbSourceOptions = {
filter: '.node-anchor', // 触发连线的区域
/* "span"表示标签,".className"表示类,"#id"表示元素id*/
filterExclude: false,
anchor: ['TopCenter', 'RightMiddle', 'BottomCenter', 'LeftMiddle'],
allowLoopback: false
}
export const jsplumbTargetOptions = {
filter: '.node-anchor',
/* "span"表示标签,".className"表示类,"#id"表示元素id*/
filterExclude: false,
anchor: ['TopCenter', 'RightMiddle', 'BottomCenter', 'LeftMiddle'],
allowLoopback: false
}
在父组件引入配置文件和方法
import { jsplumbSetting, jsplumbConnectOptions, jsplumbSourceOptions, jsplumbTargetOptions } from './config/commonConfig'
接下来在上面说的初始化方法文件里面配置鼠标滚轮缩放插件的方法 this.initPanZoom():
// 鼠标滚动放大缩小
initPanZoom() {
const mainContainer = this.jsPlumb.getContainer()
const mainContainerWrap = mainContainer.parentNode
const pan = panzoom(mainContainer, {
smoothScroll: false,
bounds: true,
// autocenter: true,
zoomDoubleClickSpeed: 1,
minZoom: 0.5,
maxZoom: 2,
// 设置滚动缩放的组合键,默认不需要组合键
beforeWheel: (e) => {
// console.log(e)
// let shouldIgnore = !e.ctrlKey
// return shouldIgnore
},
beforeMouseDown: function(e) {
// allow mouse-down panning only if altKey is down. Otherwise - ignore
var shouldIgnore = e.ctrlKey
return shouldIgnore
}
})
this.jsPlumb.mainContainerWrap = mainContainerWrap
this.jsPlumb.pan = pan
// 缩放时设置jsPlumb的缩放比率
pan.on('zoom', e => {
const { scale } = e.getTransform()
this.jsPlumb.setZoom(scale)
})
pan.on('panend', (e) => {
})
// 平移时设置鼠标样式
mainContainerWrap.style.cursor = 'grab'
mainContainerWrap.addEventListener('mousedown', function wrapMousedown() {
this.style.cursor = 'grabbing'
mainContainerWrap.addEventListener('mouseout', function wrapMouseout() {
this.style.cursor = 'grab'
})
})
mainContainerWrap.addEventListener('mouseup', function wrapMouseup() {
this.style.cursor = 'grab'
})
},
大功告成,data的数据放在这里,测试使用:
{
"FlowJson": {
"nodeList": [
{
"type": "start",
"nodeName": "已新建",
"id": "start-HiXWf8wsAcrWXjAAXVWc6AQk00000001",
"node_code": "已新建",
"trigger_event": "",
"branch_flow": "",
"icon": "play-circle",
"x": 175,
"y": 60,
"width": 50,
"height": 50
},
{
"type": "freedom",
"nodeName": "待审批",
"id": "freedom-YakFJzZ5VSp3Gec6ZULD2JDK00000004",
"node_code": "待审批",
"trigger_event": "",
"branch_flow": "",
"icon": "sync",
"x": 330,
"y": 160,
"width": 50,
"height": 120
},
{
"type": "end",
"nodeName": "已通过",
"id": "end-JjRvtD5J2GIJKCn8MF7IYwxh00000999",
"node_code": "已通过",
"trigger_event": "",
"branch_flow": "",
"icon": "stop",
"x": 330,
"y": 360,
"width": 50,
"height": 50
},
{
"type": "end",
"nodeName": "审批拒绝",
"id": "end-J1DMScH5YjSKyk0HeNkbt62F00010001",
"node_code": "审批拒绝",
"trigger_event": "",
"branch_flow": "",
"icon": "stop",
"x": 500,
"y": 350,
"width": 50,
"height": 50
}
],
"linkList": [
{
"type": "link",
"id": "link-BpI6ZuX1bJywz5SEi3R5QaWoi7g3QiSr",
"sourceId": "start-HiXWf8wsAcrWXjAAXVWc6AQk00000001",
"targetId": "freedom-YakFJzZ5VSp3Gec6ZULD2JDK00000004",
"label": "LINE000000",
"role": [],
"organize": [],
"audit_role": [],
"audit_organize": [],
"audit_organize_same": "0",
"audit_dealer_same": "0",
"audit_dealers": [],
"notice": "0",
"plug": "",
"pass_option": "pass",
"row_par_json": "",
"judge_fields": "",
"auth_at": "",
"auth_user": "",
"auth_stat": "",
"auth_mark": "",
"cls": {
"linkType": "Flowchart",
"linkColor": "#008000",
"linkThickness": 4
}
},
{
"type": "link",
"id": "link-5xJWzGlkIpUCsjmpfgesJxAOMHwkPlno",
"sourceId": "freedom-YakFJzZ5VSp3Gec6ZULD2JDK00000004",
"targetId": "end-J1DMScH5YjSKyk0HeNkbt62F00010001",
"label": "LINE000001",
"role": [],
"organize": [],
"audit_role": [
"PROJECT_SUPPORT_PLAN_CODE"
],
"audit_organize": [],
"audit_organize_same": "0",
"audit_dealer_same": "0",
"audit_dealers": [],
"notice": "0",
"plug": "",
"pass_option": "reject",
"row_par_json": "",
"judge_fields": "",
"auth_at": "",
"auth_user": "",
"auth_stat": "",
"auth_mark": "",
"cls": {
"linkType": "Flowchart",
"linkColor": "#808080",
"linkThickness": 1
}
},
{
"type": "link",
"id": "link-g05V3usXa86wAtpcMkvGzybdBlpasMjU",
"sourceId": "freedom-YakFJzZ5VSp3Gec6ZULD2JDK00000004",
"targetId": "end-JjRvtD5J2GIJKCn8MF7IYwxh00000999",
"label": "LINE000002",
"role": [],
"organize": [],
"audit_role": [
"PROJECT_SUPPORT_PLAN_CODE"
],
"audit_organize": [],
"audit_organize_same": "0",
"audit_dealer_same": "0",
"audit_dealers": [],
"notice": "0",
"plug": "",
"pass_option": "approve",
"row_par_json": "",
"judge_fields": "",
"auth_at": "",
"auth_user": "",
"auth_stat": "",
"auth_mark": "",
"cls": {
"linkType": "Flowchart",
"linkColor": "#808080",
"linkThickness": 1
}
}
]
}
}
相关文章
- 三国志8重制版虚构特典剧本介绍说明 10-30
- 暗喻幻想暗黑法师解锁方法攻略分享 10-30
- 暗喻幻想元素大师解锁方法攻略分享 10-30
- 暗喻幻想地下纳骨堂锁住的门打开方法 10-30
- 暗喻幻想6月22日玛丽亚位置一览 10-30
- 暗喻幻想巫师阿基态解锁方法分享 10-30
