Q: bpmn.js是什麼? 🤔️css
」
bpmn.js是一個BPMN2.0渲染工具包和web建模器, 使得畫流程圖的功能在前端來完成.前端
Q: 我爲何要寫該系列的教材? 🤔️vue
」
由於公司業務的須要於是要在項目中使用到bpmn.js
,可是因爲bpmn.js
的開發者是國外友人, 所以國內對這方面的教材不多, 也沒有詳細的文檔. 因此不少使用方式不少坑都得本身去找.在將其琢磨完以後, 決定寫一系列關於它的教材來幫助更多bpmn.js
的使用者或者是期於找到一種好的繪製流程圖的開發者. 同時也是本身對其的一種鞏固.git
因爲是系列的文章, 因此更新的可能會比較頻繁, 您要是無心間刷到了且不是您所須要的還請諒解😊.github
不求贊👍不求心❤️. 只但願能對你有一點小小的幫助.web
通過前面幾章的學習, 相信你們都已經掌握了自定義palette
和renderer
, 這一章節主要講解的是自定義contextPad
.hexo
先讓咱們來回顧一下, contextPad
是什麼?app
如圖, 能夠看到除了在左側的工具欄處能添加節點以外, 點擊節點的時候也會出現一個小彈窗, 這裏面也能夠添加節點. 這個小彈窗就是 contextPad
.編輯器
那麼, 經過閱讀你能夠學習到:ide
ContextPad
基礎上修改讓咱們接着在LinDaiDai/bpmn-vue-custom案例項目上進行開發.
在components
文件夾下新建一個custom-context-pad.vue
文件, 同時配置路由「自定義contextPad」.
在components/custom
文件夾下新建一個CustomContextPad.vue
文件, 用來自定義contextPad
.
CustomContextPad.vue
代碼其實自定義contextPad
和palette
很像, 只不過是使用contextPad.registerProvider(this)
來指定它是一個contextPad
, 而自定義palette
是用platette.registerProvider(this)
.
代碼以下:
// CustomContextPad.js
export default class CustomContextPad {
constructor(config, contextPad, create, elementFactory, injector, translate) {
this.create = create;
this.elementFactory = elementFactory;
this.translate = translate;
if (config.autoPlace !== false) {
this.autoPlace = injector.get('autoPlace', false);
}
contextPad.registerProvider(this); // 定義這是一個contextPad
}
getContextPadEntries(element) {}
}
CustomContextPad.$inject = [
'config',
'contextPad',
'create',
'elementFactory',
'injector',
'translate'
];
複製代碼
相信你們都已經看出來了, 重點仍是在於getContextPadEntries
這個方法, 接下來讓咱們來構建這個方法.
getContextPadEntries
代碼其實這個方法, 須要返回的也是一個對象, 也就是你要在contextPad
這個容器裏顯示哪些自定義的元素, 好比我這裏須要給容器裏添加一個lindaidai-task
的元素, 那麼咱們能夠在返回的對象中添加上append.lindaidai-task
這個屬性.
而屬性值就是這個元素的一系列配置, 和palette
中同樣, 包括:
tools、event、gateway、activity
等等,用於分類
大概是這樣:
// CustomContextPad.js
getContextPadEntries(element) {
return {
'append.lindaidai-task': {
group: 'model',
className: 'icon-custom lindaidai-task',
title: translate('建立一個類型爲lindaidai-task的任務節點'),
action: {
click: appendTask,
dragstart: appendTaskStart
}
}
};
}
複製代碼
接下來就是構建appendTask
和appendTaskStart
// CustomContextPad.js
getContextPadEntries(element) {
const {
autoPlace,
create,
elementFactory,
translate
} = this;
function appendTask(event, element) {
if (autoPlace) {
const shape = elementFactory.createShape({ type: 'bpmn:Task' });
autoPlace.append(element, shape);
} else {
appendTaskStart(event, element);
}
}
function appendTaskStart(event) {
const shape = elementFactory.createShape({ type: 'bpmn:Task' });
create.start(event, shape, element);
}
return {
'append.lindaidai-task': {
group: 'model',
className: 'icon-custom lindaidai-task',
title: translate('建立一個類型爲lindaidai-task的任務節點'),
action: {
click: appendTask,
dragstart: appendTaskStart
}
}
};
}
}
複製代碼
這裏和palette
中有一點不一樣, 就是多了一層autoPlace
的判斷, 其實我也沒太搞明白這個autoPlace
的做用是什麼, 自動放置? 並且官方給的例子🌰就是這麼寫的, 有知道的小夥伴還請評論區留言哦, 謝謝~
contextPad
的相關樣式此時咱們看看效果吧😄...
咿~ 好像能夠耶, 可是, 這個小積木也過小了一點吧😅, 並且鼠標移上去以後, 黃色的背景色直接就覆蓋它了...
哇, 這不能忍啊...
得想法子解決它, 還我漂亮的小積木❤️...
接着讓咱們打開控制檯審查元素, 能夠發現這個背景色是一個叫.djs-context-pad .entry
的類提供的樣式, 也許, 咱們能夠全局修改這個樣式, 讓咱們試試看:
/* app.css */
/* 自定義 contextPad 的樣式 */ .djs-context-pad .lindaidai-task.entry:hover { background: url('hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/rules.png') center no-repeat!important; background-size: cover!important; }
.djs-context-pad .entry:hover { /* 從新修改了 hover 以後的樣式 */ border: 1px solid #1890ff; }
複製代碼.djs-context-pad .entry { box-sizing: border-box; background-size: 94%; transition: all 0.3s; } 複製代碼
打開頁面看看效果哈.
不錯, 解決了, 哈哈😄.
(直接修改樣式雖然不是最好的解決辦法, 但這是目前我能想到的辦法, 並且它確實也可以解決問題)
ContextPad
一樣的, 若是你已經學會了在默認的ContextPad
基礎上修改, 那麼徹底自定義ContextPad
也就差很少了😁.
不過徹底自定義ContextPad
不是叫contextPad
, 而是contextPadProvider
, 好像要更厲害一點🤭...
OK👌, 讓咱們在customModeler/custom
文件夾下新建一個CustomContextPadProvider.js
文件.
CustomContextPadProvider.js
代碼先讓咱們來看下主要的結構:
// CustomContextPadProvider.js
export default function ContextPadProvider(contextPad, config, injector, translate, bpmnFactory, elementFactory, create, modeling, connect) {
this.create = create
this.elementFactory = elementFactory
this.translate = translate
this.bpmnFactory = bpmnFactory
this.modeling = modeling
this.connect = connect
config = config || {}
if (config.autoPlace !== false) {
this._autoPlace = injector.get('autoPlace', false)
}
contextPad.registerProvider(this)
}
ContextPadProvider.$inject = [
'contextPad',
'config',
'injector',
'translate',
'bpmnFactory',
'elementFactory',
'create',
'modeling',
'connect'
]
ContextPadProvider.prototype.getContextPadEntries = function(element) {}
複製代碼
別看上面代碼很長的樣子, 其實沒啥東西:
ContextPadProvider
類, 而後引入一些咱們後面要用到的方法或者屬性
$inject
注入進來
getContextPadEntries
方法
getContextPadEntries
代碼你應該也發現了, 重點仍是重寫getContextPadEntries
這個方法.
額, 這裏我先以一個簡單的爲例, 先只是建立一個lindaidai-task
. 所以能夠直接把在默認的ContextPad基礎上修改案例中的getContextPadEntries
中的代碼複製過來:
// CustomContextPad.js
getContextPadEntries(element) {
const {
autoPlace,
create,
elementFactory,
translate
} = this;
function appendTask(event, element) {
if (autoPlace) {
const shape = elementFactory.createShape({ type: 'bpmn:Task' });
autoPlace.append(element, shape);
} else {
appendTaskStart(event, element);
}
}
function appendTaskStart(event) {
const shape = elementFactory.createShape({ type: 'bpmn:Task' });
create.start(event, shape, element);
}
return {
'append.lindaidai-task': {
group: 'model',
className: 'icon-custom lindaidai-task',
title: translate('建立一個類型爲lindaidai-task的任務節點'),
action: {
click: appendTask,
dragstart: appendTaskStart
}
}
};
}
}
複製代碼
此時讓咱們先看看效果哈:
效果好像是實現了, 並且點擊和拖拽它也能實現建立lindaidai-task
的效果...
但總感受好像少了什麼, 由於光建立task
類型但元素是不夠的呀, 可不能夠建立線或者實現編輯, 刪除元素的功能呢? 固然能夠啦, 哈哈😄.
不過這一章節先說這麼多, 如何建立線和實現編輯, 刪除我會把它放到一下章來細講哈😊, 不用着急.
上面👆案例用的都是同一個項目🦐
項目案例Git地址: LinDaiDai/bpmn-vue-custom 喜歡的小夥伴請給個Star
🌟呀, 謝謝😊
系列相關推薦: