vue项目中使用bpmn-基础篇

内容概述

本系列“vue 项目中使用 bpmn-xxxx”分为七篇,均为自己使用过程中用到的实例,手工原创,目前陆续更新中。主要包括 vue 项目中 bpmn 使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。如果转载或通过爬虫直接爬的,格式特别丑,请来原创看:我是作者原文

前情提要

vue 项目中的用到流程图 bpmn,而bpmn-js官方的文档是英文的,也没有找到 api 文档。所以只能在使用过程中,自己不断爬坑填坑了。

首先,看一眼效果图

1. 安装 bpmn-js

npm install bpmn-js --save

2. 在 main.js 中引入样式

import 'bpmn-js/dist/assets/diagram-js.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';

3.vue 页面引入并使用 bpmn

import BpmnModeler from 'bpmn-js/lib/Modeler';
import CustomPaletteProvider from './customPalette';
import camundaExtension from './resources/camunda';

4. 基本操作:前进、回退、bpmn 文件导入、导出

<template>
    <div class="containerBox">
        <el-button-group>
            <el-button type="primary" size="mini" @click="handleUndo"> 后退 </el-button>
            <el-button type="success" size="mini" @click="handleRedo"> 前进 </el-button>
            <el-button type="warning" size="mini" @click="handleDownload"> 下载 </el-button>
            <el-upload
                    style="display: inline-block;"
                    :file-list="fileList"
                    class="upload-demo"
                    action=""
                    :auto-upload="false"
                    :show-file-list="false"
                    :http-request="httpRequest"
                    :on-change="handleOnchangeFile"
                    :on-remove="handleRemove"
                    :before-remove="beforeRemove"
            >
                <el-button type="danger" size="mini"> 导入 </el-button>
            </el-upload>
        </el-button-group>
        <div id="container"></div>
    </div>
</template>
<script>
    import BpmnModeler from 'bpmn-js/lib/Modeler';
    import CustomPaletteProvider from './customPalette';
    import camundaExtension from './resources/camunda';
export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
    name: </span>'index'<span style="color: rgba(0, 0, 0, 1)">,
    data() {
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
            containerEl: </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
            bpmnModeler: </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
            fileList: []
        };
    },
    mounted() {
        </span><span style="color: rgba(0, 0, 255, 1)">this</span>.containerEl = document.getElementById('container'<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">this</span>.bpmnModeler = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BpmnModeler({
            container: </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.containerEl,
            moddleExtensions: {camunda: camundaExtension},
            additionalModules: [CustomPaletteProvider]
        });
        </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.create();
    },
    methods: {
        create() {
            </span><span style="color: rgba(0, 0, 255, 1)">this</span>.bpmnModeler.createDiagram(() =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
                </span><span style="color: rgba(0, 0, 255, 1)">this</span>.bpmnModeler.get('canvas').zoom('fit-viewport'<span style="color: rgba(0, 0, 0, 1)">);
            });
        },
        handleRemove(file) {
            </span><span style="color: rgba(0, 0, 255, 1)">for</span> (let i = 0; i &lt; <span style="color: rgba(0, 0, 255, 1)">this</span>.fileList.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (file.name === <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.fileList[i].name) {
                    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.fileList.splice(i, 1<span style="color: rgba(0, 0, 0, 1)">);
                }
            }
        },
        beforeRemove(file) {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.$confirm(`确定移除 ${file.name}?`);
        },
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 后退</span>

handleUndo() {
this.bpmnModeler.get('commandStack').undo();
},
// 前进
handleRedo() {
this.bpmnModeler.get('commandStack').redo();
},
handleDownload() {
this.bpmnModeler.saveXML({format: true}, (err, data) => {
const dataTrack
= 'bpmn';
const a
= document.createElement('a');
const name
= diagram.${dataTrack};
a.setAttribute(
'href',
data:application</span>/bpmn20-xml;charset=UTF-8,${encodeURIComponent(data)}
);
a.setAttribute(
'target', '_blank');
a.setAttribute(
'dataTrack', diagram:download-<span style="color: rgba(0, 0, 0, 1)">${dataTrack});
a.setAttribute(
'download', name);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
},
handleOnchangeFile(file) {
const reader
= new FileReader();
let data
= '';
reader.readAsText(file.raw);
reader.onload
= (event) => {
data
= event.target.result;
this.bpmnModeler.importXML(data, (err) => {
if (err) {
this.$message.info('导入失败');
}
else {
this.$message.success('导入成功');
}
});
};
}
}
}
</script>
<style lang="scss">
.containerBox {
height: calc(100vh
- 220px);
position: relative;
#container {
height: calc(
100% - 50px);
}
}
</style>

View Code

5. 后续

步骤 4 代码中,有 2 个 import,是我在后面会讲到的,代码没有摘干净就传过来了。感谢 @baogege 发现提醒。

import CustomPaletteProvider from './customPalette';

import camundaExtension from './resources/camunda';

这两句引入的含义:


第一个文件 customPalette 是自定义的左侧工具栏,如果不需要自定义,可直接把引入去掉,不影响。如果需要自定义,在我的博客这系列的第五篇里讲到了如何自定义 platter,可以借鉴一下。


第二个文件是定义各个元素拥有的属性配置。我放在了附件中(点我!我是 camunda 文件),小伙伴们自己下载一下,下载后改一下后缀,改成.json。一定要改,不然项目效果不对。(因为上传时,.json 格式不支持上传,所以我把后缀改成.js 传的)。

最近在用这个 bpmn 组件画图,遇到了很多知识点,例如预览、更新节点名字、更新节点颜色、点击 xml 获取节点 id、根据 id 获取元素实例,后续慢慢整理 ~

想获取完整源码或有问题,欢迎大家关注我的公粽号,扫下面二维码或微信搜“前端便利贴”,即可获取 ~

可爱的你可能还需要