沒有一個順手的流程繪製工具?好吧,自己動手,豐衣足食!
流程繪製工具感覺也挺常用的,而且流程圖基本上也都標準化了,標準化的東西其實是最容易做的,但是 IDEA 上卻一直沒有一個稱手的流程繪製工具,其實這也是一個機會吧哈哈,自己搞一個 IDEA 外掛~
不過這個機會留給各位正在閱讀本文的小夥伴吧,鬆哥今天跟大家介紹另外一個工具 bpmn.js,利用這個,再結合大家熟悉的 Vue,我們就可以開發出一個自己的流程繪製工具,一起來看下。
先看下效果圖:
好了,不廢話了,開搞!
1. bpmn.js
bpmn.js 是一個工具包,利用這個工具包,我們可以非常方便的在瀏覽器中建立、嵌入或者擴充套件一個 BPMN 流程圖,重要的是,這個過程非常 Easy,我們只需要少量程式碼即可實現這一目標。
不知道看文章的小夥伴們日常工作中接觸流程圖多不多,如果經常接觸的話,我估計有不少小夥伴可能都見過基於 bpmn.js 構建出來的流程圖繪製工具。
因為 flowable-ui 這種太重量級了,如果我們單純的只是想在自己的專案中嵌入一個流程繪製工具,那麼顯然 bpmn.js 是最佳選擇。
網上其實也有不少關於 bpmn.js 的文章,不過當和 Vue 整合的時候,基本上都用的是 Vue2,而這個工具在 Vue2 和 Vue3 的使用中,還是有不少差異的,今天鬆哥就以 Vue3 為例,來和小夥伴們分享一下這個工具在 Vue3 中的使用。
2. + Vue3
2.1 專案建立
首先我們執行如下命令,來建立一個 Vue3 專案:
npm create vite@latest bpmn_demo --template vue cd bpmn_demo npm install npm run dev
建立完成後,我們先來裝上 bpmn.js 所需要的依賴,一共是三個依賴:
- bpmn-js
這是最核心的流程繪製工具了。
- bpmn-js-properties-panel
這是 bpmn-js 的屬性面板,流程圖中的每一個節點都有屬性,如果需要配置這些資料,就需要用到這個依賴,小夥伴們看看下圖中右邊的部分,就是這個依賴實現的功能:
- camunda-bpmn-moddle
如果你的流程引擎使用了 Camunda,那麼可以通過 camunda-bpmn-moddle 模組來配置該流程所支援的任務屬性。
好啦,廢話不多說,先把這三個依賴依次安裝上:
npm install bpmn-js npm install bpmn-js-properties-panel npm install camunda-bpmn-moddle
另外,鬆哥親測,還需要安裝 @bpmn-io/properties-panel 和 inherits 用以解決依賴內部的相容性問題,安裝命令如下:
npm i @bpmn-io/properties-panel npm i inherits
另外,專案中用到了一個 ElementUI 的按鈕,所以需要安裝上 ElementUI-Plus,如下:
npm install element-plus --save
裝好之後,我給大家看下我安裝的版本,都是目前最新版:
{ "name": "bpmn_demo", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { "@bpmn-io/properties-panel": "^0.19.0", "bpmn-js": "^9.4.0", "bpmn-js-properties-panel": "^1.5.0", "camunda-bpmn-moddle": "^6.1.2", "element-plus": "^2.2.14", "inherits": "^2.0.4", "vue": "^3.2.37" }, "devDependencies": { "@vitejs/plugin-vue": "^3.0.3", "vite": "^3.0.7" } }
鬆哥親測,如果使用 Webpack 而不是 Vite 來構建專案的話,那麼可以不用安裝 inherits,這個小夥伴們根據自己的實際情況安裝即可,專案建立完成後,如果提示缺少這個元件就安裝一下,如果不提示那就忽略即可。
2.2 開發頁面
用 Vite 新建的專案預設沒有安裝路由,配路由也比較麻煩,所以我這裡就省事一些,我直接新建一個元件來寫我們的頁面,將來在 App.vue 中引入我這個新建的元件即可。
首先我新建一個名為 BpmnView 的元件,然後在這個元件中配置 bpmn.js,內容如下:
<div> <div class="containers" style="display: flex;width:100%;height: 96vh"> <div class="canvas" style="width: 100%" id="canvas"></div> <div id="properties"> </div> </div> <div style="display:flex;justify-content: flex-end"> <el-button @click="downloadXML" type="primary" :icon="Download">下載</el-button> </div> </div>
小夥伴們看到,這個頁面整體上分為兩部分,上面是我們繪製的主區域,包括繪圖區以及屬性設定區;下面則放了一個下載流程圖 XML 檔案的按鈕。
在上面的主繪製區,我們放了兩個東西,一個是畫布 canvas,另一個是屬性 properties,canvas 就是流程圖繪製時候的核心區域,properties 則是流程中的每一個節點的屬性配置。
參考下圖,大家就知道 canvas 和 properties 分別表示什麼了:
接下來我們先來初始化左邊的 canvas。
2.2.1 canvas
首先我們來看下左邊的 Canvas 該如何初始化。
<script setup> import { onMounted} from 'vue'; import BpmnModeler from 'bpmn-js/lib/Modeler'; let bpmnModeler; onMounted(() => { // 建模 bpmnModeler = new BpmnModeler({ container: '#canvas' }) bpmnModeler.createDiagram(); }) </script>
這個初始化工作在 onMounted 回撥中完成。
建立 BpmnModeler 並設定畫布。
呼叫 createDiagram 方法開始繪圖。
配置完成後,還要記得在 main.js 中引入樣式檔案,如下:
import 'bpmn-js/dist/assets/diagram-js.css' import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css' import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css' import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
現在就可以了,左邊可以開始畫流程圖了。
2.2.2 properties
再來看右邊屬性的配置。
首先在 main.js 中加入右邊屬性的樣式檔案:
import 'bpmn-js-properties-panel/dist/assets/properties-panel.css'
然後繼續在 BpmnView.vue 中進行配置即可:
<script setup> import {onMounted} from 'vue'; import BpmnModeler from 'bpmn-js/lib/Modeler'; import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule, CamundaPlatformPropertiesProviderModule } from 'bpmn-js-properties-panel'; import CamundaExtensionModule from 'camunda-bpmn-moddle/lib'; import camundaModdleDescriptors from 'camunda-bpmn-moddle/resources/camunda'; let bpmnModeler; onMounted(() => { // 建模 bpmnModeler = new BpmnModeler({ container: '#canvas', propertiesPanel: { parent: '#properties' }, additionalModules: [ BpmnPropertiesPanelModule, BpmnPropertiesProviderModule, CamundaPlatformPropertiesProviderModule, CamundaExtensionModule ], moddleExtensions: { camunda: camundaModdleDescriptors } }) bpmnModeler.createDiagram(); }) </script>
在建立 BpmnModeler 的時候,通過 propertiesPanel 去指定 parent 的位置,再把另外五個額外的模組掛載上去就行了,這五個模組分別代表不同的屬性,我就不挨個說了,小夥伴們可以自行嘗試刪除掉一個屬性,看看哪些屬性少了,就知道這個模組的功能了。
2.2.3 下載按鈕
最後再來看看下載按鈕的點選事件。
function downloadXML() { bpmnModeler.saveXML({format: true}, (err, xml) => { if (!err) { console.log(xml); // 獲取檔名 const name = getFileName(xml); // 把輸就轉換為URI,下載要用到的 const encodedData = encodeURIComponent(xml); const downloadLink = document.createElement('a'); if (xml) { // 將資料給到連結 downloadLink.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData; // 設定檔名 downloadLink.download = name; // 觸發點選事件開始下載 downloadLink.click(); } } }) } function getFileName(xml) { let split = xml.split('process id="'); return split[1].split('" ')[0]+".bpmn20.xml"; }
呼叫 bpmnModeler.saveXML 方法,回撥中的 xml 引數就是生成的流程圖 XML 檔案,然後建立一個虛擬的 a 標籤,模擬一個點選事件即可完成下載。
getFileName 方法則是從下載的 XML 檔案中截取出來 bpmn:process 標籤的 id 值作為檔名,這也符合我們日常的命名習慣。
好啦,大功告成!以後就可以使用我們自己的流程繪製工具來畫流程圖了。
不過有一個小小遺憾,就是這個是針對 Camunda 這個流程引擎的,如果所以他畫出來的流程圖並不能直接用在 Flowable 中,如果想在 Flowable 中使用,還需要一點額外的定製,這個咱們以後再說。
3. 小結
bpmn.js 最大的優勢在於可以根據自己專案的需求,方便的嵌入到已有專案中。好啦,公眾號江南一點雨後臺回覆 bpmn_demo 可以下載文字完整案例。
- Spring中實現非同步呼叫的方式有哪些?
- 帶引數的全型別 Python 裝飾器
- 整理了幾個Python正則表示式,拿走就能用!
- 設計模式之狀態模式
- 如何實現資料庫讀一致性
- SOLID:開閉原則Go程式碼實戰
- React中如何引入CSS呢
- 慢查詢 MySQL 定位優化技巧,從10s優化到300ms
- 一個新視角:前端框架們都卷錯方向了?
- 編碼中的Adapter,不僅是一種設計模式,更是一種架構理念與解決方案
- 手寫程式語言-遞迴函式是如何實現的?
- 一文搞懂模糊匹配:定義、過程與技術
- 新來個阿里 P7,僅花 2 小時,做出一個多執行緒永動任務,看完直接跪了
- Puzzlescript,一種開發H5益智遊戲的引擎
- @Autowired和@Resource到底什麼區別,你明白了嗎?
- “四招”守護個人資訊保安
- CSS transition 小技巧!如何保留 hover 的狀態?
- React如此受歡迎離不開這4個主要原則
- 我是怎麼入行做風控的
- 重溫三十年前對於 NN 的批判:神經網路無法實現可解釋 AI