vue3的bpmn使用

news2025/1/24 14:46:59

目录

1.前言

2.安装相关依赖

3.组件部分的template部分

4.组件中的script

5.style代码

6.父组件中的使用场景

7.注意事项


1.前言

由于此次处于自己做项目阶段,基本上只要项目中需要使用到流程这一方面的东西,就需要用到bpmn以及后端的activity流,网络上大多数都是vue2的写法,而且方法都是写一半一半的,并且bpmn的官方文档也都是英文,所以我自己封装了一个bpmn的组件,我的项目中使用在了elementui中的dialog中。

请多多点赞收藏,作者不易,谢谢大家,注解全写在代码中,很详细,若还有疑问欢迎讨论区见。

2.安装相关依赖

 c-scrollbar这个包是我为了让右侧的属性栏实现滚动效果而导入的,具体详情可以百度搜索c-scrollbar的用法,我这边只是简单使用

3.组件部分的template部分

<template>
    <div class="container" style="position:relative;height:550px;">
        //此处必须ref绑定,这样才能获取到dom元素,才能后面的操作
        <div class="canvas" ref="canvas"></div>
        //此处简单使用scrollbar,此处为右侧属性栏的html代码
        <el-scrollbar height="93%" style="width:300px; position:absolute;top:0px;right:0px;">
            <div id="js-properties-panel" class="panel"></div>
        </el-scrollbar>
        //此处我放置了几个按钮,导出和部署,导出的ref绑定也是必要的
        <ul class="buttons">
            <li class="item download">
                <a class="btn" @click="exportBPMN" ref="exportbtn">导出</a>
            </li>
            <li class="item submit" v-if="props.isAdd">
                <a class="btn" @click="deploy">
                    部署
                </a>
            </li>
        </ul>
    </div>
</template>

4.组件中的script

<script setup>
import { ref, onMounted } from 'vue'
// 绘制流程图
import BpmnModeler from 'bpmn-js/lib/Modeler'
//此处是个后端书写的接口作用是:(将我这边将bpmn保存为xml的文件存入到数据库中)
import { addDeploymentByString } from "@/api/activiti/definition";
// 预览流程图
import BpmnViewer from "bpmn-js/lib/Viewer"
//右侧属性栏
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'
// 汉化组件
import customTranslate from './customTranslate/customTranslate';
//汉化组件的引入使用
var customTranslateModule = {
    translate: ['value', customTranslate]
};
const props = defineProps({
    //xml字符串用于后面创建转化显示
    xmlStr: {
        type: String,
        default: ""
    },
    //是否为查看
    isPreview: {
        type: Boolean,
        default: true
    },
    //是否为新增
    isAdd: {
        type: Boolean,
        default: false
    },
    //高亮节点数组
    highPoint: {
        type: Array,
        default: []
    },
    //当前用户所处理节点数组
    iDo: {
        type: Array,
        default: []
    },
    //等待处理节点数组
    waitingToDo: {
        type: Array,
        default: []
    },
    //高亮线数组
    highLine: {
        type: Array,
        default: []
    },
});
let exportbtn = ref(null)
let bpmnModeler = ref(null);
let container = ref(null);
let canvas = ref(null);
//此处定义了子组件向父组件传递事件作用是(将dialog框不显示,然后刷新列表)此处事件应写在父组件
const emits = defineEmits(["handleExportSuccess"]);
//挂载时初始化
onMounted(() => {   
    init()
})
//更新时初始化
onUpdated(() => {
    //更新时先销毁原实例
    bpmnModeler.destroy()
    init()
})
function init() {
    if (props.isPreview) {
        //预览时候创建实例为BpmnViewer
        bpmnModeler = new BpmnViewer({ // 仅预览
            container: canvas.value
        })
    } else {
        //可操作时候创建实例为BpmnModeler
        bpmnModeler = new BpmnModeler({
            container: canvas.value,
            propertiesPanel: {
                parent: '#js-properties-panel'
            },
            additionalModules: [
                //右侧工具栏以及节点
                propertiesProviderModule,
                propertiesPanelModule,
                //汉化
                customTranslateModule
            ],
            moddleExtensions: {
                camunda: camundaModdleDescriptor
            }

        })
    }
    createNewDiagram()
}
// 将字符串转换成图显示出来
function createNewDiagram() {
    let xmlStrChange = '`' + props.xmlStr + '`'
    //此处判断是否是新增,若是新增固定一个xml的字符串,若字符串为空,那么久无法在画布上编辑,所以我下面就赋值了一个只存在一个节点的xml字符串
    if (props.isAdd) {
        //bpmn2:process属性修改为isExecutable="true就可以默认勾选可执行文件
        xmlStrChange = `
<?xml version="1.0" encoding="UTF-8"?>
  <bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:bpmn2="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"
        id="sample-diagram"
        targetNamespace="http://bpmn.io/schema/bpmn"
        xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
  <bpmn2:process id="Process_1" isExecutable="true">
    <bpmn2:startEvent id="StartEvent_1" />
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="192" y="82" width="36" height="36" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>`
    }
    //importXML()方法后的第一个参数是一个xml字符串,第二个参数为回调err为失败时候的信息
    bpmnModeler.importXML(xmlStrChange, (err) => {
        if (err) {
            console.error(err)
        } else {
            //通常这里会写个成功时候的回调,但是我的组件分为预览与新增,所以我这边判断是否为预览,预览的话进行节点颜色改变等
            if (props.isPreview) {
                //此处获取画布对象,用于后面的节点颜色改变
                const bpmnCanvas = bpmnModeler.get('canvas')
                //获取需要高亮显示的节点
                let highPointNode = props.highPoint;
                let highLineNode = props.highLine;
                let iDoNode = props.iDo
                let waitingToDoNode = props.waitingToDo
                //画布居中显示
                bpmnCanvas.zoom('fit-viewport', 'auto')
                //设置节点颜色,setNodeColor具体查看下面的函数
                setNodeColor(highPointNode, "highlightPoint", bpmnCanvas);
                setNodeColor(highLineNode, "highlightLine", bpmnCanvas);
                setNodeColor(iDoNode, "highlightiDo", bpmnCanvas);
                setNodeColor(waitingToDoNode, "highlightiwaiting", bpmnCanvas);
            }
            // 这里是成功之后的回调, 可以在这里做一系列事情
            success()
        }
    })
}
function success() {
    // console.log('创建成功!')
}
//部署按钮事件
function deploy() {
    //获取bpmn产生的xml文件
    bpmnModeler.saveXML().then(res => {
        //此处为存入数据库的接口,此处需要你们后端根据自己项目去提供接口,有关activity流
        addDeploymentByString({
            stringBPMN: res.xml
        }).then(res => {
            console.log("产生成功");
        })

    })
    //向父组件传方法,用于后面的dialog消失以及列表更新
    emits("handleExportSuccess")
}
//导出按钮事件
function exportBPMN() {
    //saveXML为bpmn提供的api,用于保存为xml,并导出,第一个参数格式保存,正常一样,第二个参数的err为错误值,xml为导出的xml字符串
    bpmnModeler.saveXML({ format: true }, function (err, xml) {
        //此函数转码xml并下载,详情请看以下setEncoded定义
        setEncoded(
            exportbtn.value,
            "diagram.bpmn",
            //判断是否报错,报错则为null三元表达式
            err ? null : xml
        );
    });
    //向父组件传方法,用于后面的dialog消失以及列表更新
    emits("handleExportSuccess")
}
// 设置高亮颜色的class(nodeCodes为需要设置高亮的节点ID数组,colorClass为设置的类名,canvas为画布对象)类名详情请看style样式
function setNodeColor(nodeCodes, colorClass, canvas) {
    for (let i = 0; i < nodeCodes.length; i++) {
        if (nodeCodes[i] == null) {
            continue
        } else {
            canvas.addMarker(nodeCodes[i], colorClass);
        }

    }
}
// 转码xml并下载
// @param {object} link 按钮(需要是dom对象)
// @param {string} name 下载名称 (文件名)任取
// @param {string} data base64XML
function setEncoded(link, name, data) {
    var encodedData = encodeURIComponent(data);
    if (data) {
        link.href="data:application/bpmn20-xml;charset=UTF-8," + encodedData
        link.download=name
    }
};
</script>

5.style代码

<style lang="scss">
.container {
    width: 100%;
    height: 100%;

}
//以下几个都是设置的高亮,通过设置类名来控制高亮颜色,此处自定义,可以通过f12开发者工具查看类名来自己定义样式记得样式后面加上!important
//设置高亮点的样式颜色(对应组件参数中的highPoint)
.highlightPoint:not(.djs-connection) .djs-visual> :nth-child(1),
.highlightPoint:not(.djs-connection) .djs-visual>path {
    fill: #ebeaea !important;
    /* color elements as green */
    stroke: #ebeaea !important;
}

//设置高亮线的样式颜色(对应组件参数中的highLine)
.highlightLine {
    .djs-visual {
        path {
            fill: #008000 !important;
            stroke-width: 2px !important;
            stroke: #008000 !important;
            stroke-linejoin: round !important;
            marker-end: url("#sequenceflow-end-green-green-3lfjjpcx65dm9ix6p7cd7oo3y") !important;
        }
    }
}
//设置高亮IDO的样式颜色(对应组件参数中的iDo)
.highlightiDo:not(.djs-connection) .djs-visual> :nth-child(1),
.highlightiDo:not(.djs-connection) .djs-visual>path {
    fill: #a8d894 !important;
    /* color elements as green */
    stroke: #008000 !important;
}
//设置高亮waitingToDo的样式颜色(对应组件参数中的waitingToDo)
.highlightiwaiting:not(.djs-connection) .djs-visual> :nth-child(1),
.highlightiwaiting:not(.djs-connection) .djs-visual>path {
    fill: #ffff0d !important;
    /* color elements as green */
    stroke: #008000 !important;
}

.canvas {
    width: 100%;
    height: 100%;

}

.scrollbar-demo-item {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 50px;
    margin: 10px;
    text-align: center;
    border-radius: 4px;
    background: var(--el-color-primary-light-9);
    color: var(--el-color-primary);

    .panel {
        width: 300px;
    }

}


.buttons {
    position: absolute;
    bottom: 0px;

    li {
        /* display: inline-block; */
        margin-right: 10px;
        height: 26px;
        line-height: 26px;
        float: left;
        list-style: none;

        .btn {
            background: #00BCD4;
            border: none;
            outline: none;
            padding: 0px 10px;
            color: #fff;
            display: inline-block;
            opacity: 1;
            height: 26px;
            font-size: 14px;
            line-height: 26px;
        }
    }

}
</style>

6.父组件中的使用场景

通常会以对话框的形式使用

        

 <!-- 查看进度话框 -->
    <el-dialog v-model="modelVisible" title="进度查询" width="1480px" append-to-body>
      <BpmnView @handleExportSuccess="handleExportSuccess" :modelVisible="modelVisible" :iDo="iDo" :waitingToDo="waitingToDo" :highLine="highLine" :highPoint="highPoint" :xmlStr="xml" :isPreview="true" :isAdd="isAdd"></BpmnView>
    </el-dialog>

7.注意事项

1.此组件中包含了高亮显示节点的部分,若需要则直接复制,不需要则需删除对应内容,需要则要满足前面传的高亮节点数组

2.style不能加scoped不然高亮无法显示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/407915.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VUE3 之 render 函数的使用 - 这个系列的教程通俗易懂,适合自学

目录 1. 概述 2. render 函数 3. 综述 4. 个人公众号 1. 概述 老话说的好&#xff1a;不用想的太多、太远&#xff0c;做好当天的事&#xff0c;知道明天要做什么就可以了。 言归正传&#xff0c;今天我们来聊聊 VUE 中 render 函数的使用。 2. render 函数 2.1 一个简单…

前缀和与对数器与二分法

1. 前缀和 假设有一个数组&#xff0c;我们想大量频繁的去访问L到R这个区间的和&#xff0c;我们该怎么快速的得出。 如果我们每次都遍历一遍累加这样就太慢了。我们可以开辟一个数组&#xff0c;把每个位置的和加在一起存进去。 如果我们要找的L到R中&#xff0c;L是0。那么…

Echarts地图的基本使用方法

echarts使用地图的基本使用方法 引入echarts 第一步&#xff1a;引入js文件 下载的最新完整版本 echarts.min.js 即可 <script src"echarts.min.js"> </script>第二步&#xff1a;指定DOM元素作为图表容器 创建一个DOM来作为绘制图表的容器 <di…

理解vuex实现的原理

一、vuex是什么&#xff1f; Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c; 这个状态管理应用包含以下几个部分&#xff1a; state&#xff0c;驱动应用的数据源&#xff1b;view&#xff0c;以声明方式将 stat…

【工具】Vue中生成二维码组件——vue-qr

【工具】Vue中生成二维码组件——vue-qr npm地址——https://www.npmjs.com/package/vue-qr 注&#xff1a;不支持IE浏览器 效果 1、安包 npm install vue-qr --save 2、引入 // vue2.0 import VueQr from vue-qr // vue3.0 import VueQr from vue-qr/src/packages/vue-qr.…

3分钟搞懂阿里云服务器安装Nginx并配置静态访问页面

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【Bug 终结者】 &#xff0c;【CSDN新星创作者】&#x1f3c6;&#xff0c;阿里云技术博主&#x1f3c6;&#xff0c;51CTO人气博主&#x1f3c6;&…

怎么让 echarts 图表动起来?定时器解决它 —— 大屏展示案例(动态仪表盘、动态柱状图)

该案例为了实现效果采用的是随机生成数据&#xff0c;比较适用于偏向展示效果的静态页面如门户网站的首页、登录页等等。颜色样式自调。 需要注意在有些项目中仪表盘可能无法正常显示&#xff0c;这是因为你在项目中引入的 echarts 版本太低&#xff0c;需要引入新版本 echarts…

一个简单的springboot+Vue前后端框架搭建

前言 根据网上的一些教程试着搭建了一个简单的前后端分离的用户管理系统。该系统使用Vue框架编写前端代码&#xff0c;Springboot编写后端代码&#xff0c;Mysql作为数据库存储系统的数据。本文着重介绍整个项目的搭建流程以及附加一些在搭建过程的想法和注意事项。 一、Vue及…

【vue+router】解决路由重复警告:[vue-router] Duplicate named routes definition

vue页面动态添加路由&#xff0c;但加载页面会报警告&#xff1a; [vue-router] Duplicate named routes definition: { name: "xxx", path: "xxx" }这个问题解释为&#xff1a;路由命名重复 网上有一些大神剔除原有路由的做法&#xff1a; 1、古墩古墩 …

vue中computed的详细讲解

vue中computed的详细讲解1.定义2.用法3.computed的响应式依赖(缓存)4.应用场景1.定义 computed是vue的计算属性&#xff0c;是根据依赖关系进行缓存的计算&#xff0c;只有在它的相关依赖发生改变时才会进行更新 2.用法 一般情况下&#xff0c;computed默认使用的是getter属性…

Vue组件传值(props属性,父到子,子到父,兄弟传值)

文章目录[TOC](文章目录)前言一、props是什么&#xff1f;使用规则二、父传子 props实现步骤代码实现效果展示二.子传父 $emit实现步骤代码实现效果展示三.兄弟传值 EventBus实现步骤代码实现效果展示总结前言 Vue是数据驱动视图更新的框架, 平时写业务时,都会把页面不同模块拆…

CSS - 浮动布局(float)

目录 标准布局 标准流 浮动与浮动流&#xff0c;及元素脱标概念 浮动元素 浮动的特点 浮动带来的问题&#xff1a;标准流父级容器高度塌陷 清除浮动 浮动布局 margin负值 标准布局 CSS将所有的元素都当成盒子&#xff0c;CSS布局其实就是如何堆放盒子。 在说浮动布局…

【玩转CSS】学成在线(文末素材源码自取)

&#x1f525;一个人走得远了&#xff0c;就会忘记自己为了什么而出发&#xff0c;希望你可以不忘初心&#xff0c;不要随波逐流&#xff0c;一直走下去&#x1f3b6; &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; &#x1f984; …

vue监听缓存数据(localStorage) 中值的更新

2个vue组件之间数据同步&#xff0c;可以通过监听localStorage数据变化&#xff0c;来改变数据的值。 方法&#xff1a;可以重写localStorage的setItem方法&#xff0c;当调用setItem方法设置新值的时候&#xff0c;会new Event(setItemEvent) 用window.dispatchEvent()这个…

vue 项目兼容 IE 浏览器

前言 : 网上 找了很多关于 vue项目兼容 IE 浏览器的 教程步骤 , 写的 非常详细 , 但根据我自己的项目,怎么找 都没有找到 webpack.base.conf.js 这个文件 ,就没办法配置 因为 vue-cli最新版本原因 , 隐藏了配置文件, 所有的 都在 vue.config.js中配置 可以根据自己的 vue-cli 版…

手摸手带你玩转Vue3——Vue2升级Vue3

今年年初&#xff0c;尤大大公布了一个重磅消息&#xff0c;将Vue3作为Vue的默认版本。 这无疑不是对我们开发人员的内卷煽风点火&#xff01; vue默认版本改动意味着&#xff0c;官方将会把Vue研发重心放到vue3上&#xff0c;vue2也开始走下坡路&#xff0c;至于淘汰过时只是…

前端插件库之vue3使用element-plus实现登录、注册页面和忘记密码弹窗,以及已有样式的覆盖

vue3使用element-plus实现登录/注册页面登录/注册页面组件预览添加忘记密码弹窗预览已有样式的修改1.字体大小2.router-link默认样式登录/注册页面组件 vue3 的登录和注册页面 目前只有框架和函数框架, 根据具体需要填充, 已有功能: 1.没有勾选同意使用手册, 登录和注册按钮是…

后端返回各种图片形式在前端的转换及展示

一、 接口返回的图片显示如下所示&#xff1a;&#xff08;在控制台看的&#xff09;返回的是这个图片&#xff08;二进制&#xff09; 可是&#xff0c;在 打印的时候&#xff0c;返回的却是 出现问题的原因的axios 默认返回的是 json 文本形式&#xff0c;二进制图片数据被强…

TS复习-----TS中的函数

目录 一、ts函数的定义 二、ts中定义函数传参 1.函数传参方法 2.可选参数 3.默认参数 4.剩余参数 函数重载 一、ts函数的定义 函数是一种特殊的对象&#xff0c;可以被调用。TS 里的函数和原生&#xff0c;ES 6 里的函数差不太多&#xff0c;只是多了一些其他功能。 //…

HTML入门学习笔记+详细案例

✨HTML入门学习笔记详细案例 作者介绍: &#x1f393;作者:偷偷敲代码的青花瓷&#x1f431;‍&#x1f680; &#x1f440;作者的Gitee:代码仓库 ✨✨我和大家一样都是热爱编程✨,很高兴能在此和大家分享知识,希望在分享知识的同时,能和大家一起共同进步,取得好成绩&#x1f9…