项目中使用到bpmnjs
的时候,大多数情况都是需要自定义定制才能满足需求,因此bpmnjs
的自定义基本不可避免,今天我们来进行vue
中的bpmnjs的Modeler
自定义过程;
由于bpmnjs
自定义过程稍微复杂,刚开始理解起来有些难度,不懂的地方大家耐心多看几遍;
首先自定义要先继承原Modeler,再将需要自定义的模块(CustomModule)
与原有模块(modules)
合并(或者说覆盖)
import inherits from "inherits";
import Modeler from "bpmn-js/lib/Modeler";
import CustomModule from "../custom/index.js";
function CustomModeler(options) {
Modeler.call(this, options);
this._customElements = [];
}
inherits(CustomModeler, Modeler);
CustomModeler.prototype._modules = [].concat(CustomModeler.prototype._modules, [CustomModule]);
export { CustomModeler };
被引用的自定义模块CustomModule
的custom/index.js
文件(这个文件很重要,以后几乎所有需要自定义引入的模块都在这里import
)内容参考如下,假设自定义了左侧工具栏模块:
import paletteProvider from "../customPalette/paletteprovider";
import customPalette from "../customPalette/palette";
export default {
__init__: [
"paletteProvider",
'palette'
],
paletteProvider: ["type", paletteProvider],
palette: [ 'type', customPalette ],
};
结构目录参考图:
经过以上两步,自定义的CustomModeler对象就出来了,然后将上面的代码整理好放在不同的目录等待引用,下面是CustomModeler的参数设置与使用方法:
<div ref="bpmnbox" class="canvas-box"></div>
import customTranslate from '@/components/bpmnProcess/customTranslate/customTranslate';
import flowableDescriptor from '@/components/bpmnProcess/properties-panel/descriptor/flowable.json';
import flowableMoudle from '@/components/bpmnProcess/properties-panel/extension-moddle/flowable';
export default{
data(){
return{
}
},
methods:{
async getModeler(){
const { CustomModeler } = await require('@/components/bpmnProcess/customModeler')
let modeler = await new CustomModeler({
container: this.$refs.bpmnbox,
keyboard: {
bindTo: window
},
height: '100%',
moddleExtensions: {
flowable: flowableDescriptor
},
additionalModules: [
flowableMoudle,
{ //汉化
translate: ['value', customTranslate]
},
{
// 禁用滚轮滚动
zoomScroll: ["value", ""]
}
]
})
return modeler
}
}
}
以上的三个自定义模块customTranslate、flowableDescriptor、flowableMoudle的js文件分别参考如下:
- customTranslate:汉化模块
上面的translations参考内容如下(汉化键值对):import translations from './translations'; export default function customTranslate(template, replacements) { replacements = replacements || {}; // Translate template = translations[template] || template; // Replace return template.replace(/{([^}]+)}/g, function(_, key) { return translations[replacements[key]] || replacements[key] || '{' + key + '}'; }); }
export default { 'Task': '任务', 'Process': '流程', 'UserTask': '用户任务', 'GateWay': '网关', 'StartEvent': '开始事件', 'EndEvent': '结束事件', }
- flowableDescriptor:扩展属性相关描述文件
{ "name": "Flowable", "uri": "http://flowable.org/bpmn", "prefix": "flowable", "xml": { "tagAlias": "lowerCase" }, "associations": [], "types": [ { "name": "UserTask", "isAbstract": true, "extends": [ "bpmn:UserTask", "bpmn:MultiInstanceLoopCharacteristics" ], "properties": [ { "name": "timerEventDefinition", "type": "Expression" },{ "name": "multiInstanceLoopCharacteristics", "type": "MultiInstanceLoopCharacteristics" }] }, { "name": "StartEvent", "isAbstract": true, "extends": [ "bpmn:StartEvent" ], "properties": [ { "name": "timerEventDefinition", "type": "Expression" } ] }, { "name":"Properties", "isAbstract": true, "extends":[], "superClass":["Element"], "meta":{ "allowedIn":["*"] }, "properties":[ { "name":"values", "isMany":true, "isbody":true, "type":"Formright" } ] }, { "name":"Formright", "isAbstract": true, "extends":[ "flowable:Exec_before", "flowable:Exec_after" ], "superClass":["Element"], "meta":{ "allowedIn":["*"] }, "properties":[ { "name":"value", "isAttr":true, "type":"String" }, { "name": "body", "isBody": true, "type": "String" } ] }, { "name": "Property", "superClass": [ "Element" ], "properties": [ { "name": "id", "type": "String", "isAttr": true }, { "name": "name", "type": "String", "isAttr": true }, { "name": "value", "type": "String", "isAttr": true } ] } ] } //参考官方仓库:https://github.com/bpmn-io/moddle/blob/master/docs/descriptor.md
flowableMoudle:扩展属性模块
module.exports = { __init__:["FlowableModdleExtension"], FlowableModdleExtension:["type",require("./flowableExtension")] }
flowableExtension文件内容参考如下(其实这些文件全都可以在依赖目录找到,只是需要替换成’flowable’):
"use strict"; var some = require("min-dash").some; var ALLOWED_TYPES = { FailedJobRetryTimeCycle: ["bpmn:StartEvent", "bpmn:BoundaryEvent", "bpmn:IntermediateCatchEvent", "bpmn:Activity"], Connector: ["bpmn:EndEvent", "bpmn:IntermediateThrowEvent"], Field: ["bpmn:EndEvent", "bpmn:IntermediateThrowEvent"] }; function is(element, type) { return element && typeof element.$instanceOf === "function" && element.$instanceOf(type); } function exists(element) { return element && element.length; } function includesType(collection, type) { return ( exists(collection) && some(collection, function(element) { return is(element, type); }) ); } function anyType(element, types) { return some(types, function(type) { return is(element, type); }); } function isAllowed(propName, propDescriptor, newElement) { var name = propDescriptor.name, types = ALLOWED_TYPES[name.replace(/flowable:/, "")]; return name === propName && anyType(newElement, types); } function FlowableModdleExtension(eventBus) { eventBus.on( "property.clone", function(context) { var newElement = context.newElement, propDescriptor = context.propertyDescriptor; this.canCloneProperty(newElement, propDescriptor); }, this ); } FlowableModdleExtension.$inject = ["eventBus"]; FlowableModdleExtension.prototype.canCloneProperty = function(newElement, propDescriptor) { if (isAllowed("flowable:FailedJobRetryTimeCycle", propDescriptor, newElement)) { return ( includesType(newElement.eventDefinitions, "bpmn:TimerEventDefinition") || includesType(newElement.eventDefinitions, "bpmn:SignalEventDefinition") || is(newElement.loopCharacteristics, "bpmn:MultiInstanceLoopCharacteristics") ); } if (isAllowed("flowable:Connector", propDescriptor, newElement)) { return includesType(newElement.eventDefinitions, "bpmn:MessageEventDefinition"); } if (isAllowed("flowable:Field", propDescriptor, newElement)) { return includesType(newElement.eventDefinitions, "bpmn:MessageEventDefinition"); } }; module.exports = FlowableModdleExtension;
使用例子:
this.modeler = await this.getModeler()
拿到modeler实例以后,怎么获取Modeler各模块?
this.eventBus = this.modeler.get("eventBus") this.modeling = this.modeler.get("modeling") this.moddle = this.modeler.get("moddle") this.bpmnFactory = this.modeler.get("bpmnFactory") this.elementRegistry = this.modeler.get("elementRegistry") this.canvas = this.modeler.get("canvas") this.selection = this.modeler.get("selection")
到这里,Modeler的自定义以及相关的引用就已经完成了,能看到这里的同学很不错了,可能一开始可能是比较难理解的,只能多看几遍慢慢吸收,接下来的篇章就是分解自定义左侧工具栏、自定义右侧属性栏等等相关的内容,感谢你的耐心阅读。
引导:
关于bpmnjs+vue的更多篇章,小编已经全部整理在这里:
bpmnjs+vue中文文档API常见方法使用总结