vue项目中使用bpmn-基础篇
内容概述
本系列“vue项目中使用bpmn-xxxx”分为七篇,均为自己使用过程中用到的实例,手工原创,目前陆续更新中。主要包括vue项目中bpmn使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。如果转载或通过爬虫直接爬的,格式特别丑,请来原创看:
前情提要
经过前四篇的学习,我们能够实现bpmn基本绘图、预览、为节点加事件加颜色等效果,这一篇我们来说,如何自定义左侧工具栏(platter),首先看一下自定义前后效果图对比:
我们本次要实现的目标:基于左侧platter原有元素类型,创建出一个新的自定义节点。暂且叫它“草莓蛋糕”节点,类型是 bpmn:task, 样式我们自己找一个好看的小草莓蛋糕图案。所以,开动吧~首先新建一个“custompalette”文件夹,里面放我们今天所有自定义的文件。
步骤1:建立platter类函数,命名为custompalette.js
export default class custompalette { constructor(create, elementfactory, palette) { this.create = create; this.elementfactory = elementfactory; palette.registerprovider(this); } // 这个是绘制palette的核心,函数名不要变 getpaletteentries() { const elementfactory = this.elementfactory; const create = this.create; function drageventfactory(type) { return function (event) { const taskshape = elementfactory.create('shape', { type: type }); create.start(event, taskshape); }; } return { 'create.cake': { title: '我是自定义节点-草莓蛋糕', // 鼠标悬浮到节点上显示的文字 classname: 'icon-custom bpmn-icon-cake', // 样式名 action: { // 操作该节点时会触发的事件,此时只注册一个拖动事件即可,否则拖动时没有效果 dragstart: drageventfactory('bpmn:task') } } }; } } custompalette.$inject = [ 'create', 'elementfactory', 'palette' ];
此时,我们已经注册好了一个名称为“create.cake”的节点,拖动它时,画布中会出现一个"bpmn:task"类型的节点,此时需要将该文件导出并在页面中引入,否则没有效果。
步骤2:在custompalette.js同级,建立一个index.js文件将其导出
import custompalette from './custompalette'; export default { __init__: ['custompalette'] custompalette: ['type', custompalette], };
步骤3:页面中(index.vue)引入index.js
import custommodule from './custompalette'; export default { mounted() { this.containerel = document.getelementbyid('container'); this.bpmnmodeler = new bpmnmodeler({ additionalmodules: [ custommodule ] }); }
步骤4:为节点定义样式
新建一个custompalette.scss文件,在该文件同级放一张“cake.png”的图片,作为节点的背景图写入。背景图引入的话,貌似只支持.png格式,亲测:jpg报错
.bpmn-icon-cake { background-image: url('./cake.png'); } .icon-custom { background-size: 65%; background-repeat: no-repeat; background-position: center center; }
并且在main.js中引入,注意,一定要在main.js中全局引入,否则不生效。
import 'custompalette/custompalette.scss';
此时,我们便可以在左侧工具栏中看到自定义的“草莓蛋糕”节点了,但是此时拖动该节点,右侧只会产生一个“bpmn:task”的节点,只有一个框框。
我们希望的是,拖动后画布中也显示自定义图标,所以我们进行下一步:自定义渲染
步骤5:画布渲染自定义节点
此时需要我们新建一个 customrenderer.js文件,作用:自定义 renderer。因为我们是在bpmn原有的元素“bpmn:task”基础上进行修改,所以我们需要对将baserenderer进行继承。
import baserenderer from 'diagram-js/lib/draw/baserenderer'; // 引入默认的renderer const high_priority = 1500; // 最高优先级 export default class customrenderer extends baserenderer { // 继承baserenderer constructor(eventbus, bpmnrenderer) { super(eventbus, high_priority); this.bpmnrenderer = bpmnrenderer; } canrender(element) { return !element.labeltarget; } drawshape(parentnode, element) { const shape = this.bpmnrenderer.drawshape(parentnode, element); return shape; } getshapepath(shape) { return this.bpmnrenderer.getshapepath(shape); } } customrenderer.$inject = ['eventbus', 'bpmnrenderer'];
此时, customrenderer.js文件大概结构完成了,注意:high_priority变量和canrender不可以删掉,否则会有问题。重头戏是里面的drawshape函数。
步骤6:书写drawshape函数
我们在customrenderer.js同级建立一个util文件,记录自定义类型节点的一些属性。
import cake from './cake.png'; // 自定义元素的类型,此时我们只需要自定义一种节点,所以数组只有一个元素 const customelements = ['bpmn:task']; const customconfig = { // 自定义元素的配置 cake: { url: cake, attr: {x: 0, y: 0, width: 50, height: 50} } }; export {customelements, customconfig};
现在我们来书写drawshape函数
import { customelements, customconfig } from './util'; import { append as svgappend, create as svgcreate } from 'tiny-svg'; ... drawshape(parentnode, element) { const type = element.type; // 获取到类型 // 所有节点都会走这个函数,所以此时只限制,需要自定义的才去自定义,否则仍显示bpmn默认图标 if (customelements.includes(type)) { const {url, attr} = customconfig['cake']; const customicon = svgcreate('image', {...attr, href: url}); element['width'] = attr.width; element['height'] = attr.height; svgappend(parentnode, customicon); return customicon; } const shape = this.bpmnrenderer.drawshape(parentnode, element); return shape; }
步骤7: 导出并使用customrenderer
修改之前导出custompalette的 index.js文件
import custompalette from './custompalette'; import customrenderer from './customrenderer'; export default { __init__: ['custompalette', 'customrenderer'], custompalette: ['type', custompalette], customrenderer: ['type', customrenderer] };
注意:此时__init__内的属性名都不可以改,不要问为什么,因为改了报错。
步骤3中已经将该index.js引入到了页面中,此时无需再次引入,此时我们来看看效果。
后续
项目目录:index.vue是画布主页面,同级custompalette文件夹下共有6个文件,结构如下:
各个文件的代码片段在文中已经展示过了,文件夹不知道怎么上传到博客。如想获取完整源码或有问题,公众号联系我,扫下面二维码或公众号搜“lemoncool”,即可获取~
可爱的你可能还需要
上一篇: div滚动条自动在最底部出现
推荐阅读
-
使用vue-cli创建项目的图文教程(新手入门篇)
-
Vue学习之路第十四篇:v-for指令中key的使用注意事项
-
vue项目,webpack中配置src路径别名及使用
-
vue-cli项目中使用mockjs(基础使用和全局配置使用)
-
vue项目中使用bpmn-自定义platter的示例代码
-
javascript中10个正则表达式使用介绍基础篇
-
.NET Core实战项目之CMS 第六章 入门篇-Vue的快速入门及其使用
-
使用vue-cli创建项目的图文教程(新手入门篇)
-
第二部分 基础篇-第4章 定时器-CC2530中断方式使用定时器T3
-
在项目碰到在vue中,v-for的索引index在html中的使用方法(详细教程)