基于vue和jsplumb的工作流编辑器开发
2020/4/30 11:03:05
本文主要是介绍基于vue和jsplumb的工作流编辑器开发,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
背景
需要实现一个工作流,支持拖拽节点生成工作流。
业务实现
- 支持页面布局缩放
- 支持节点
- 支持if else
- 支持多分支
技术点
- 网格背景
- 工作流缩放
- 工作流技术实现
- 节点拖拽
技术选型
- vue
- jsplumb
- sortablejs(vue-draggable)
难点攻破
网格背景
主要是利用css的 linear-gradient
和 background-size
实现的。
<div class="flow-layout"> <div class="flow-editor"> <div class="canvas-container"> </div> </div> </div> 复制代码
.flow-layout { display: flex; flex-direction: column; } .flow-editor { position: relative; display: flex; flex-direction: row; flex: 1; overflow: hidden; } .canvas-container { flex: 1; overflow: auto; z-index: 0; } 复制代码
.canvas-container:before { content: ""; height: 10px; width: 100%; display: block; background-repeat-y: no-repeat; position: absolute; background-image: linear-gradient(90deg, #ccc 1px, transparent 0), linear-gradient(90deg, #ddd 1px, transparent 0); background-size: 75px 10px, 5px 5px; } .canvas-container:after { content: ""; height: 100%; width: 10px; display: block; background-repeat-x: no-repeat; position: absolute; top: 0; background-image: linear-gradient(#ccc 1px, transparent 0), linear-gradient(#ddd 1px, transparent 0); background-size: 10px 75px, 5px 5px; } 复制代码
工作流缩放
主要结合 css的 属性选择符 E[att="val"]
,通过修改zoom的值,来实现缩放功能。
<div class="flow-zoom" :data-zoom="canvasDataRoom + '%'"> <div class="zoom-btn"> <el-button size="mini" :class="{'el-button--primary':canvasRoomMinusEnable}" icon="el-icon-minus" circle @click="handleMinusCanvas"></el-button> </div> <div class="zoom-btn"> <el-button size="mini" :class="{'el-button--primary':canvasRoomPlusEnable}" icon="el-icon-plus" circle @click="handlePlusCanvas"></el-button> </div> </div> <div class="canvas-container" :data-zoom="canvasDataRoom"> <div class="campaignCanvas"></div> </div> 复制代码
.canvas-container[data-zoom="100"] { background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px; } .canvas-container[data-zoom="90"] { background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); background-size: 70px 70px, 70px 70px, 14px 14px, 14px 14px; } .canvas-container[data-zoom="80"] { background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); background-size: 60px 60px, 60px 60px, 12px 12px, 12px 12px; } .canvas-container[data-zoom="70"] { background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); background-size: 55px 55px, 55px 55px, 11px 11px, 11px 11px; } .canvas-container[data-zoom="60"] { background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); background-size: 45px 45px, 45px 45px, 9px 9px, 9px 9px; } .canvas-container[data-zoom="50"] { background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); background-size: 40px 40px, 40px 40px, 8px 8px, 8px 8px; } 复制代码
工作流技术实现
主要是依赖 jsplumb 实现的。
主要利用 jsplumb 实现两个节点的连接。
让dom节点变成jsplumb 可拖拽节点
<div id="_uuid"> </div> 复制代码
jsPlumb.draggable(_uuid, {}); 复制代码
两个节点的连接。
jsPlumb.connect({ source: source, target: target, endpoint: 'Dot', // 连接线的样式 connectorStyle: {strokeStyle: "#ccc", joinStyle: "round", outlineColor: "#ccc"}, // 链接 style // 连接线配置,起点可用 connector: ["Flowchart", { stub: [10, 20], gap: 1, cornerRadius: 2, alwaysRespectStubs: true }], // 链接 // endpointStyle: {fill: 'transparent', outlineStroke: 'transparent', outlineWidth: 2}, // 线的样式 paintStyle: {stroke: 'lightgray', strokeWidth: 2}, // 锚点的位置 anchor: ['BottomCenter', 'TopCenter'], // 遮罩层-设置箭头 overlays: [ ['PlainArrow', {width: 10, length: 10, location: 1}], ['Custom', { location: .5, id: 'nodeTempSmall', create: function () { let $el = that.$refs[target][0].$el; $el.dataset.target = target; $el.dataset.source = source; return $el; }, visible: false }], ['Label', {location: 1, id: "flowItemDesc", cssClass: "node-item-label", visible: true}] // ] }); 复制代码
删除一个节点
jsPlumb.removeAllEndpoints(uuid); 复制代码
两个节点之间创建节点
function createFlowConnectionLabel(sourceList, target) { if (!Array.isArray(sourceList)) { sourceList = [sourceList]; } sourceList.forEach((source) => { // let lines = this.$options.jsPlumb.getConnections({ source: source, target: target }); // lines.forEach((line) => { line.getOverlay('nodeTempSmall').setVisible(true); line.bind('click', this.handleFlowLabelClick); }); }); } 复制代码
两个节点之间的文案创建
function createFlowItemLabel(source, target, label) { this.$nextTick(() => { let lines = this.$options.jsPlumb.getConnections({ source: source, target: target }); if (lines.length > 0) { lines[0].getOverlay("flowItemDesc").setLabel(`<span class="node-item-title" title="${label}">${label}</span>`); } }); } 复制代码
节点拖拽
主要是依赖 sortablejs 实现的
主要利用vue-draggable 封装好的组件,来实现拖拽。 核心代码
拖拽的目的地区域。
<draggable class="flow-item node-temp node-temp-img" ref="tempNode" :id="flowItem.uuid" :group="{name:'sortable', pull:false, put: true }"> </draggable> 复制代码
被拖拽的目标对象。
<draggable class="items-box" :key="index" :list="flowItem.children" :group="{name:'sortable', pull: 'clone', put: false }" v-bind="dragConfig" :move="handleFlowMoveItem" @start="handleFlowMoveStart" @end="handleFlowMoveEnd" :sort="false" :ref="flowItem.ref"> <div class="node-temp-img"></div> </template> </draggable> 复制代码
项目截图
项目地址
github: github.com/bosscheng/v…
demo: bosscheng.github.io/vue-draggab…
这篇关于基于vue和jsplumb的工作流编辑器开发的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-04package.json 文件位置在哪?-icode9专业技术文章分享
- 2024-10-01Craco.js学习:从入门到实践指南
- 2024-10-01Create-React-App学习:入门与实践指南
- 2024-10-01CSS-in-JS学习:从入门到实践指南
- 2024-09-30JSX语法学习:从入门到初步掌握
- 2024-09-30Mock.js学习:入门教程与实战演练
- 2024-09-30React Hooks学习:从入门到实践
- 2024-09-30受控组件学习:React中的基础入门教程
- 2024-09-29JS定时器教程:初学者必看指南
- 2024-09-29JS对象教程:初学者的全面指南