內容概述
本系列 “vue項目中使用bpmn-xxxx” 分為七篇,均為自己使用過程中用到的實例,手工原創,目前陸續更新中。主要包括vue項目中bpmn使用實例、應用技巧、基本知識點總結和需要注意事項,具有一定的參考價值,需要的朋友可以參考一下。如果轉載或通過爬蟲直接爬的,格式特別丑,請來原創看:我是作者原文
前情提要
根據之前的操作,我們可以創建、導入、導出流程圖,並對其進預覽。通過此篇可以學到:
- 為節點添加點擊、鼠標懸浮等事件
- 獲取流程圖內所有指定類型的節點
- 通過外部更新節點名字
- 獲取節點實例的兩種方法,根據節點id拿到元素實例
來看一眼效果圖
step1:為節點添加點擊、鼠標懸浮等事件
方案:bpmnModeler中的eventBus,只要你要,只要它有
代碼:

const eventBus = this.bpmnModeler.get('eventBus'); // 注冊節點事件,eventTypes中可以寫多個事件 const eventTypes = ['element.click', 'element.hover']; eventTypes.forEach((eventType) => { eventBus.on(eventType, (e) => { const {element} = e; if (!element.parent) return; if (!e || element.type === 'bpmn:Process') { return false; } else { if (eventType === 'element.click') { // 節點點擊后想要做的處理 // 此時想要點擊節點后,拿到節點實例,通過外部輸入更新節點名稱 this.currentElement = element; } else if (eventType === 'element.hover') { // 鼠標滑過節點后想要做的處理 console.log('鼠標經過節點啦~'); } } }); });
step2:獲取流程圖內所有指定類型的節點
場景:需要獲取流程圖里所有的用戶節點信息,以列表形式展示在另外地方。查了很多文檔,並沒有找到。事實證明,源碼才是王道!
方案:elementRegistry提供了方案,並且支持過濾
代碼:
const elementRegistry = this.bpmnModeler.get('elementRegistry'); const userTaskList = elementRegistry.filter( (item) => item.type === 'bpmn:UserTask' );
step3 : 通過外部更新節點名字
方案:bpmnModeler的modeling,提供了updateLabel方法,modeling.updateLabel(節點id,新名字);
step4: 獲取節點實例的兩種方法
4.1 通過step1中的點擊事件等,可以直接拿到目標對象e,e.element就是節點實例
eventBus.on('element.click', (e) => {console.log(e.element);})
4.2 沒有任何事件可以觸發,手里空空只有一個節點id
方案:bpmnModeler的elementRegistry來解圍!
const elementRegistry = this.bpmnModeler.get('elementRegistry'); console.log(elementRegistry.get(節點id));
后續
上文代碼都是片段,特此附上完整代碼:老規矩:data中的chart變量流程圖xml文件數據,由於行數過多,附在了附件中(點我!點我),使用時,將附件內容復制過來,賦值給chart即可運行!

<template> <div class="containerBox"> <div style="margin-left: 250px"> 通過輸入框更改節點名稱: <el-input v-model.trim="nodeName" placeholder="請輸入節點名稱" clearable @input="inputChange" style="width: 200px"> </el-input> </div> <div id="container"></div> </div> </template> <script> import BpmnModeler from 'bpmn-js/lib/Modeler'; import camundaExtension from './resources/camunda'; import {tempDetail, saveCanvas} from '@api/processConfig'; export default { name: 'index', data() { return { containerEl: null, bpmnModeler: null, currentElement: {}, nodeName: "", // chart變量流程圖xml文件數據,由於行數過多,附在了附件中,使用時,將附件整個賦值給chart即可 chart: '<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">\n' + '<bpmn:process id="Process_1" isExecutable="false">\n' + '<bpmn:startEvent id="StartEvent_1">\n' + '<bpmn:outgoing>Flow_021z3si</bpmn:outgoing>\n' + '</bpmn:startEvent>\n' + '<bpmn:serviceTask id="Activity_1fru9kc" name="我是第一個節點">\n' + '<bpmn:incoming>Flow_021z3si</bpmn:incoming>\n' + '<bpmn:outgoing>Flow_1hwj8kv</bpmn:outgoing>\n' + '</bpmn:serviceTask>\n' + '<bpmn:sequenceFlow id="Flow_021z3si" sourceRef="StartEvent_1" targetRef="Activity_1fru9kc"> </bpmn:sequenceFlow>\n' + '<bpmn:userTask id="Activity_0ozmm5p" name="第二名">\n' + '<bpmn:incoming>Flow_1hwj8kv</bpmn:incoming>\n' + '<bpmn:outgoing>Flow_1tbnntc</bpmn:outgoing>\n' + '</bpmn:userTask>\n' + '<bpmn:sequenceFlow id="Flow_1hwj8kv" sourceRef="Activity_1fru9kc" targetRef="Activity_0ozmm5p"> </bpmn:sequenceFlow>\n' + '<bpmn:sequenceFlow id="Flow_1tbnntc" sourceRef="Activity_0ozmm5p" targetRef="Event_03kmy6i"> </bpmn:sequenceFlow>\n' + '<bpmn:endEvent id="Event_03kmy6i">\n' + '<bpmn:incoming>Flow_1tbnntc</bpmn:incoming>\n' + '</bpmn:endEvent>\n' + '</bpmn:process>\n' + '<bpmndi:BPMNDiagram id="BPMNDiagram_1">\n' + '<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">\n' + '<bpmndi:BPMNEdge id="Flow_021z3si_di" bpmnElement="Flow_021z3si">\n' + '<di:waypoint x="209" y="120"/>\n' + '<di:waypoint x="290" y="120"/>\n' + '</bpmndi:BPMNEdge>\n' + '<bpmndi:BPMNEdge id="Flow_1hwj8kv_di" bpmnElement="Flow_1hwj8kv">\n' + '<di:waypoint x="390" y="120"/>\n' + '<di:waypoint x="480" y="120"/>\n' + '</bpmndi:BPMNEdge>\n' + '<bpmndi:BPMNEdge id="Flow_1tbnntc_di" bpmnElement="Flow_1tbnntc">\n' + '<di:waypoint x="580" y="120"/>\n' + '<di:waypoint x="672" y="120"/>\n' + '</bpmndi:BPMNEdge>\n' + '<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">\n' + '<dc:Bounds x="173" y="102" width="36" height="36"/>\n' + '</bpmndi:BPMNShape>\n' + '<bpmndi:BPMNShape id="Activity_1fru9kc_di" bpmnElement="Activity_1fru9kc">\n' + '<dc:Bounds x="290" y="80" width="100" height="80"/>\n' + '</bpmndi:BPMNShape>\n' + '<bpmndi:BPMNShape id="Activity_0ozmm5p_di" bpmnElement="Activity_0ozmm5p">\n' + '<dc:Bounds x="480" y="80" width="100" height="80"/>\n' + '</bpmndi:BPMNShape>\n' + '<bpmndi:BPMNShape id="Event_03kmy6i_di" bpmnElement="Event_03kmy6i">\n' + '<dc:Bounds x="672" y="102" width="36" height="36"/>\n' + '</bpmndi:BPMNShape>\n' + '<bpmndi:BPMNShape id="Activity_0lkkmka_di">\n' + '<dc:Bounds x="820" y="80" width="100" height="80"/>\n' + '</bpmndi:BPMNShape>\n' + '<bpmndi:BPMNEdge id="Flow_1t2mucq_di">\n' + '<di:waypoint x="920" y="120"/>\n' + '<di:waypoint x="1012" y="120"/>\n' + '</bpmndi:BPMNEdge>\n' + '</bpmndi:BPMNPlane>\n' + '</bpmndi:BPMNDiagram>\n' + '</bpmn:definitions>' }; }, mounted() { this.containerEl = document.getElementById('container'); this.bpmnModeler = new BpmnModeler({ container: this.containerEl, moddleExtensions: {camunda: camundaExtension} }); this.showChart(); }, methods: { getShapeById() { const elementRegistry = this.bpmnModeler.get('elementRegistry'); console.log(elementRegistry.get('Activity_0ozmm5p')); }, inputChange(val) { const modeling = this.bpmnModeler.get('modeling'); if (JSON.stringify(this.currentElement) === '{}') { this.$message.info('請保證要更改的節點處於選中狀態!'); return false; } else { modeling.updateLabel(this.currentElement, val); } }, // 流程圖回顯 showChart() { this.bpmnModeler.importXML(this.chart, (err) => { if (!err) { this.addEventBusListener(); this.getNodeInfoList(); this.getShapeById(); } }); }, // 獲取流程圖中所有節點信息 getNodeInfoList() { const elementRegistry = this.bpmnModeler.get('elementRegistry'); const userTaskList = elementRegistry.filter( (item) => item.type === 'bpmn:UserTask' ); // 此時得到的userTaskList 便是流程圖中所有的用戶節點的集合 console.log(userTaskList); }, addEventBusListener() { const eventBus = this.bpmnModeler.get('eventBus'); // 注冊節點事件,eventTypes中可以寫多個事件 const eventTypes = ['element.click', 'element.hover']; eventTypes.forEach((eventType) => { eventBus.on(eventType, (e) => { const {element} = e; if (!element.parent) return; if (!e || element.type === 'bpmn:Process') { return false; } else { if (eventType === 'element.click') { // 節點點擊后想要做的處理 // 此時想要點擊節點后,拿到節點實例,通過外部輸入更新節點名稱 this.currentElement = element; } else if (eventType === 'element.hover') { // 鼠標滑過節點后想要做的處理 console.log('鼠標經過節點啦~'); } } }); }); } } }; </script> <style lang="scss"> .containerBox { height: calc(100vh - 220px); position: relative; #container { height: calc(100% - 50px); } } </style>
想獲取完整源碼或有問題,歡迎大家關注我的公粽號,掃下面二維碼或微信搜“前端便利貼”,即可獲取~