当前位置: 代码迷 >> 综合 >> bpmn.js在vue中发送http请求
  详细解决方案

bpmn.js在vue中发送http请求

热度:8   发布时间:2023-12-12 02:52:54.0

之前使用的是本地写死的 xml 字符串来渲染流程图,实际开发中肯定不满足我们的需求,那么我们应该如何解决这个问题呢?

常用的做法是:前端发送 axios 请求,获取到 xml 的字符串,然后使用 bpmn.js 中的 importXML 的方法将 xml 字符串转换为图形在页面上渲染出来。

接下来进入正题啦~

bpmn.js在vue中发送http请求

通过http请求获取并渲染数据

还是在之前创建好的项目 vue-bpmn 的基础上添加代码

先在项目中安装 axios 用于发送 http 请求

npm i axios --save-D

然后在 views 文件夹下新建 axios.vue 的文件,并配置好路由规则

// axios.vue
<template><div class="container"><template v-if="loading"><div class="loading">Loading</div></template><template v-else><div class="canvas" ref="canvas"></div><div id="js-properties-panel" class="panel"></div></template></div>
</template>

css 部分的样式

<style scoped> .container {
    position: relative;width: 100%;height: 100%;
}
.canvas {
    width: 100%;height: 100%;
}
.panel {
    position: absolute;top: 0;right: 0;width: 300px;
}
</style>

然后在 js 部分引入 axios 并模拟向后端发送请求获取并渲染数据

<script>
import axios from 'axios'
import BpmnModeler from 'bpmn-js/lib/Modeler'
// 引入一个本地的xml字符串,若是没有获取到后台的数据则用它
import {
     xmlStr } from '../mock/xmlStr'// 使用右侧属性栏
import propertiesPanelModule from 'bpmn-js-properties-panel'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
export default {
    data () {
    return {
    bpmnModeler: null, // bpmn 建模器container: null,canvas: null,loading: true,xmlUrl: '',defaultXmlStr: xmlStr}},mounted() {
    this.init()},methods: {
    async init () {
    this.loading = truethis.xmlUrl = await this.getXmlUrl()console.log(this.xmlUrl)this.loading = false// 等待 DOM 更新之后再对工作流进行初始化this.$nextTick(() => {
    this.initBpmn()})},// 该方法模拟请求后台获取 bpmn 文件getXmlUrl () {
    return new Promise(resolve => {
    setTimeout(() => {
    const url = 'https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/bpmnMock.bpmn'resolve(url)}, 1000)})},initBpmn () {
    // 获取canvas的dom节点const canvas = this.$refs.canvas// 建模this.bpmnModeler = new BpmnModeler({
    container: canvas,// 添加控制板propertiesPanel: {
    parent: '#js-properties-panel'},additionalModules: [// 右边的属性栏propertiesProviderModule,propertiesPanelModule],moddleExtensions: {
    camunda: camundaModdleDescriptor}})this.createNewDiagram()},async createNewDiagram () {
    const that = thislet bpmnXmlStr = ''if (this.xmlUrl === '') {
     // 若是后台没有数据则使用默认的一个 xmlbpmnXmlStr = this.defaultXmlStrthis.transformCanvas(bpmnXmlStr)} else {
    let res = await axios({
    method: 'get',timeout: 120000,url: that.xmlUrl,headers: {
     'Content-Type': 'multipart/form-data' }})console.log(res)bpmnXmlStr = res['data']this.transformCanvas(bpmnXmlStr)}},transformCanvas (bpmnXmlStr) {
    // 将字符串转换成图显示出来try {
    const result = this.bpmnModeler.importXML(bpmnXmlStr)const {
     warnings } = resultconsole.log(warnings)this.success()// 让图能自适应屏幕var canvas = this.bpmnModeler.get('canvas')canvas.zoom('fit-viewport')} catch (err) {
    console.log(err.message, err.warnings)}},success () {
    console.log('创建成功')}}
}
</script>

效果演示

在这里插入图片描述

请求接口来源 多谢

编辑之后将最新的bpmn发送给后台

仅仅涉及到数据渲染是远远不够的,如果我们修改了数据,该怎么把数据发送给后台并存储呢?

这个问题就涉及到 bpmn.js 中的事件绑定,需要给图形绑定一个事件 来检测到图形的改变,并获取到最新的 xml 信息发送给后台

views 文件夹下新建一个 save.vue 文件,并将 axios.vue 中的内容复制到 save.vue 中,同时记得配置路由哦
success() 方法中新增一个 addBpmnListener() 的方法

// save.vue
<script>success () {
    console.log('创建成功')this.addBpmnListener()},// 添加绑定事件addBpmnListener () {
    // 给图绑定事件,当图有发生改变的时候就会触发这个事件this.bpmnModeler.on('commandStack.changed', () => {
    this.saveDiagram((err, xml) => {
    console.log(xml) // 这里获取到的就是最新的 xml 信息})})},// 下载为 bpmn 格式,done 是个函数,调用的时候传入的saveDiagram (done) {
    // 把传入的 done 再传给 bpmn 原型的 saveXML 函数调用this.bpmnModeler.saveXML({
     format: true }, (err, xml) => {
    done(err, xml)})}
</script>

编辑图后,就能获得最新的 xml 内容

在这里插入图片描述

编辑完后保存为bpmn文件或svg文件

通过监听 commandStack.changed 事件我们就能获取到修改完成之后最新的 xml 信息了
我们可以了最新的 xml 信息传递给后台,也可以直接下载为 bpmn/svg 文件

views 文件夹下新建 download.vue 并配置好路由规则,把 save.vue 的内容复制到 download.vue
先给添加两个按钮,这两个按钮先隐藏(因为此时 href 中没有连接),待图更新完后显示出来供用户下载

    <template v-else><a href="javascript:;" ref="saveBpmn" class="hidden">保存为bpmn</a><a href="javascript:;" ref="saveSvg" class="hidden">保存为svg</a><div class="canvas" ref="canvas"></div><div id="js-properties-panel" class="panel"></div></template>

然后修改 js 部分的代码

<script>
methods: {
    // 添加绑定事件addBpmnListener () {
    const downloadLink = this.$refs.saveBpmnconst downloadSvgLink = this.$refs.saveSvg// 给图绑定事件,当图有发生改变的时候就会触发这个事件this.bpmnModeler.on('commandStack.changed', () => {
    downloadLink.display = 'block'downloadSvgLink.display = 'block'this.saveBpmn((err, xml) => {
    this.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml) // 这里获取到的 xml 就是最新的 xml 信息})this.saveSvg((err, svg) => {
    this.setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg)})})},// 下载为 Svg 格式,done 是个函数,调用的时候传入的saveSvg (done) {
    // 把传入的 done 再传给 bpmn 原型的 saveSVG 函数调用this.bpmnModeler.saveSVG(done)},// 下载为 bpmn 格式,done 是个函数,调用的时候传入的saveBpmn (done) {
    // 把传入的 done 再传给 bpmn 原型的 saveXML 函数调用this.bpmnModeler.saveXML({
     format: true }, (err, xml) => {
    done(err, xml)})},// 当图发生改变的时候会调用这个函数,这个 data 就是图的 xmlsetEncoded (link, name, data) {
    // 把 xml 转换为 URI,下载要用到的const encodeData = encodeURIComponent(data)// 下载图的具体操作,改变 a 的属性,className 另 a 标签可点击,href 可以下载,download 是下载的文件的名字console.log(link, name, data)let xmlFile = new File([data], 'test.bpmn')console.log(xmlFile)if (data) {
    link.className = 'active'// 将数据给到连接link.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodeData// 设置文件名link.download = name}}
}
</script>

效果演示

在这里插入图片描述

  相关解决方案