首页 前端知识 BPMN-JS在Vue3中的自定义

BPMN-JS在Vue3中的自定义

2024-05-31 19:05:14 前端知识 前端哥 971 593 我要收藏

文章目录

具体呈现效果

汉化包自定义

Pinia存储所需数据

组件自定义

组件左侧栏框的自定义

组件操作栏框的自定义

渲染组件的自定义

封装组件

调整Task大小弹框

总结


项目环境:

"vue": "^3.4.15"

"sass": "^1.71.1"

"element-plus": "^2.5.6"

"pinia": "^2.1.7"

"bpmn-js": "^17.0.2"

"bpmn-js-properties-panel": "^5.13.0"

"min-dash": "^4.2.1"

"tiny-svg": "^4.0.0"

"diagram-js": "^14.1.0"

具体呈现效果

汉化包自定义

 src/utils/bpmn/tanslatetranslations.js

const translations = {
  Name: '名称',
  Value: '值',
  ID: '唯一标识(ID)',
  General: '基础属性',
  Documentation: '文档',
  'Element documentation': '元素文档说明',
  Executable: '可执行的',

  'Activate hand tool': '拖动屏幕',
  'Change element': '改变元素',
  'Activate global connect tool': '连接',
  'Activate lasso tool': '套索',
  'Activate create/remove space tool': '创建/删除空间',
  'Create start event': '开始事件',
  'Create intermediate/boundary event': '中间/边界事件',
  'Create end event': '结束事件',
  'Create gateway': '网关',
  'Create task': '任务',
  'Create expanded sub-process': '扩展子流程',
  'Create data store reference': '数据存储引用',
  'Create data object reference': '数据对象引用',
  'Create pool/participant': '池/参与者',
  'Create group': '团队',

  'Append end event': '结束事件',
  'Append gateway': '网关',
  'Append task': '任务',
  'Append intermediate/boundary event': '中间/边界事件',
  'Add text annotation': '文本注释',
  Delete: '删除',
  'Connect to other element': '连接另一个元素',

  'Add lane above': '上方添加通道',
  'Divide into two lanes': '分成两条通道',
  'Divide into three lanes': '分成三条通道',
  'Add lane below': '下方添加通道',
}

export const customTranslate = (template, replacements) => {
  replacements = replacements || {}

  template = translations[template] || template

  return template.replace(/{([^}]+)}/g, (_, key) => {
    return replacements[key] || '{' + key + '}'
  })
}

注:可能部分翻译不到位请谅解,毕竟是需要符合本人使用时习惯所翻译。而其中并未导入所有的汉化内容,而是根据本人使用具体使用时,用到的部分汉化。

Pinia存储所需数据

src\stores\index.js

import { createPinia } from 'pinia'

const pinia = createPinia()

export default pinia

export * from './bpmn'

src\stores\bpmn.js 

import { defineStore } from 'pinia'
import { ref, toRaw } from 'vue'

export const useBpmnStore = defineStore(
  'bpmn',
  () => {
    //存储链接所需信息
    const linkAppendServiceLinkEnd = ref('')
    //存储bpmn的操作所需要的对象
    const modeler = ref()
    const elementRegistry = ref()

    //控制调整Task大小弹窗的弹出与关闭
    const bpmnObjectInformation = ref({
      isOpen: false,
      windowName: '编辑元素宽高',
      item: {},
      baseWidth: 0,
      baseHeight: 0,
      open: function (item) {
        this.item = item
        this.baseWidth = item.width
        this.baseHeight = item.height
        this.isOpen = true
      },
      close: function () {
        this.isOpen = false
      },
      //关键函数,负责重设某个元素的大小
      resetItem: function () {
        let modeling = modeler.value.get('modeling')
        modeling.resizeShape(toRaw(this.item), {
          x: this.item.x,
          y: this.item.y,
          width: parseInt(this.baseWidth),
          height: parseInt(this.baseHeight)
        })

        this.isOpen = false
      }
    })

    const getLinkAppendServiceLinkEnd = () => {
      return linkAppendServiceLinkEnd.value
    }

    const setLinkAppendServiceLinkEnd = (newLinkAppendServiceLinkEnd) => {
      linkAppendServiceLinkEnd.value = newLinkAppendServiceLinkEnd
    }

    const removeLinkAppendServiceLinkEnd = () => {
      linkAppendServiceLinkEnd.value = ''
    }

    //获取bpmn的操作所需要的对象
    const setModeler = (newModeler, newElementRegistry) => {
      modeler.value = newModeler
      elementRegistry.value = newElementRegistry
    }

    return {
      getLinkAppendServiceLinkEnd,
      setLinkAppendServiceLinkEnd,
      removeLinkAppendServiceLinkEnd,
      setModeler,
      bpmnObjectInformation
    }
  }
)

组件自定义

这部分主要是为了自定义组件,并能够显示出来,能够实现颜色、大小等自定义。

src\utils\bpmn\palette\index.js

import CustomContextPad from './CustomContextPad'
import CustomPalette from './CustomPalette'
import CustomRenderer from './CustomRenderer'

/**
 * 在基础上添加CustomPalette/CustomContextPad的自定义(保留最开始的组件)
 */
// export default {
//   __init__: ['customContextPad', 'customPalette', 'customRenderer'],
//   customPalette: ['type', CustomPalette],
//   customContextPad: ['type', CustomContextPad],
//   customRenderer: ['type', CustomRenderer]
// }

/**
 * CustomPalette/CustomContextPad的自定义(不保留最开始的组件)
 */
export default {
  __init__: ['contextPadProvider', 'paletteProvider', 'customRenderer'],
  paletteProvider: ['type', CustomPalette],
  contextPadProvider: ['type', CustomContextPad],
  customRenderer: ['type', CustomRenderer]
}

src/assets/bpmn.scss

//作为css文件,为后续渲染操作栏中各个元素颜色提供条件
.canvas {
  width: 100%;
  height: 100%;
}

.properties {
  position: absolute;
  top: 16px;
  right: 24px;
  width: 210px;
  flex: 1;
  z-index: 1;
}

.general-education-compulsory-course {
  color: rgba(249, 197, 153, 1) !important;
}

.subject-based-course {
  color: rgba(141, 177, 226, 1) !important;
}

.professional-basic-compulsory-course {
  color: rgba(242, 220, 218, 1) !important;
}

.practice-section {
  color: rgba(153, 255, 204, 1) !important;
}

.strong-link {
  color: rgba(93, 93, 93, 1) !important;
}

.week-link {
  color: rgba(163,187,223, 1) !important;
}

src\utils\bpmn\palette\item.js

//存储一些基本信息,确保自定义文件中的信息不会产生歧义
const itemColor = {
  'general-education-compulsory-course': '#f9c599',
  'subject-based-course': '#8db1e2',
  'professional-basic-compulsory-course': '#f2dcda',
  'practice-section': '#99ffcc',
  'strong-link': '#5d5d5d',
  'week-link': '#a3bbdf'
}

const itemText = {
  'general-education-compulsory-course': '通识必修课',
  'subject-based-course': '学科基础课',
  'professional-basic-compulsory-course': '专业基础必修课',
  'practice-section': '实践部分'
}

const itemClass = {
  'strong-link': 'marker-strong-end',
  'week-link': 'marker-week-end'
}

const General_Education_Compulsory_Course = 'general-education-compulsory-course'
const Subject_Based_Course = 'subject-based-course'
const Professional_Basic_Compulsory_Course = 'professional-basic-compulsory-course'
const Practice_Section = 'practice-section'
const Strong_Link = 'strong-link'
const Week_Link = 'week-link'

export {
  itemColor,
  itemText,
  itemClass,
  General_Education_Compulsory_Course,
  Subject_Based_Course,
  Professional_Basic_Compulsory_Course,
  Practice_Section,
  Week_Link,
  Strong_Link
}

组件左侧栏框的自定义

src\utils\bpmn\palette\CustomPalette.js

import '@/assets/bpmn.scss'
import { General_Education_Compulsory_Course, Subject_Based_Course, Professional_Basic_Compulsory_Course, Practice_Section} from './item'

export default class CustomPalette {
  constructor(bpmnFactory, create, elementFactory, palette, translate) {
    this.bpmnFactory = bpmnFactory
    this.create = create
    this.elementFactory = elementFactory
    this.translate = translate

    palette.registerProvider(this)
  }
  // 这个函数就是绘制palette的核心
  getPaletteEntries() {
    const { bpmnFactory, create, elementFactory, translate } = this

    //构建Task,作为最基本元素,操作它可以类比出其他的组件
    function createTask(suitabilityScore) {
      return function (event) {
        const businessObject = bpmnFactory.create('bpmn:Task')
        const documentationObject = bpmnFactory.create('bpmn:Documentation')
        documentationObject.text = suitabilityScore
        //存储数据到document中,方便于后端获取,以及重新渲染
        businessObject.documentation = [documentationObject]
        businessObject.suitable = suitabilityScore

        const shape = elementFactory.createShape({
          type: 'bpmn:Task',
          businessObject: businessObject,
          height: 40
        })

        create.start(event, shape)
      }
    }

    // 返回需要的组件
    return {
      'create.general-education-compulsory-course': {
        group: 'activity',
        //控制操作栏中元素的颜色
        className: 'bpmn-icon-task general-education-compulsory-course',
        //控制操作栏中元素的提示文字
        title: translate('通识必修课'),
        action: {
          //控制操作栏中元素的各种函数
          dragstart: createTask(General_Education_Compulsory_Course),
          click: createTask(General_Education_Compulsory_Course)
        }
      },
      'create.subject-based-course': {
        group: 'activity',
        className: 'bpmn-icon-task subject-based-course',
        title: translate('学科基础课'),
        action: {
          dragstart: createTask(Subject_Based_Course),
          click: createTask(Subject_Based_Course)
        }
      },
      'create.professional-basic-compulsory-course': {
        group: 'activity',
        className: 'bpmn-icon-task professional-basic-compulsory-course',
        title: translate('专业基础必修课'),
        action: {
          dragstart: createTask(Professional_Basic_Compulsory_Course),
          click: createTask(Professional_Basic_Compulsory_Course)
        }
      },
      'create.practice-section': {
        group: 'activity',
        className: 'bpmn-icon-task practice-section',
        title: translate('事件部分'),
        action: {
          dragstart: createTask(Practice_Section),
          click: createTask(Practice_Section)
        }
      }
    }
  }
}

CustomPalette.$inject = ['bpmnFactory', 'create', 'elementFactory', 'palette', 'translate']

组件操作栏框的自定义

src\utils\bpmn\palette\CustomContextPad.js

import '@/assets/bpmn.scss'
import { General_Education_Compulsory_Course, Subject_Based_Course, Professional_Basic_Compulsory_Course, Practice_Section, Strong_Link, Week_Link } from './item'
import { useBpmnStore } from '@/stores'

const bpmnStore = useBpmnStore()

export default class CustomContextPad {
  constructor(
    bpmnFactory,
    contextPad,
    create,
    elementFactory,
    translate,
    modeling,
    globalConnect,
    connect
  ) {
    this.bpmnFactory = bpmnFactory
    this.create = create
    this.elementFactory = elementFactory
    this.translate = translate
    this.modeling = modeling
    this.globalConnect = globalConnect
    this.connect = connect
    this.suitabilityScore = undefined

    contextPad.registerProvider(this)
  }

  getContextPadEntries(element) {
    const { bpmnFactory, create, elementFactory, translate, modeling, connect } = this

    //构建Task,作为最基本元素,操作它可以类比出其他的组件
    function appendServiceTaskStart(suitabilityScore) {
      return function (event) {
        const businessObject = bpmnFactory.create('bpmn:Task')
        const documentationObject = bpmnFactory.create('bpmn:Documentation')
        documentationObject.text = suitabilityScore
        //存储数据到document中,方便于后端获取,以及重新渲染
        businessObject.documentation = [documentationObject]

        businessObject.suitable = suitabilityScore

        const shape = elementFactory.createShape({
          type: 'bpmn:Task',
          businessObject: businessObject,
          height: 40
        })

        create.start(event, shape, element)
      }
    }

    //连接开始时,pinia存储所需要渲染的数据,由于不知道如何在渲染结束时获取数据
    function appendServiceLinkStart(suitabilityScore) {
      return function (event) {
        // this.suitabilityScore = suitabilityScore
        bpmnStore.setLinkAppendServiceLinkEnd(suitabilityScore)
        connect.start(event, element, undefined)
      }
    }

    //连接结束时,从pinia存储的数据中,取出所需要存储在document中的数据,并存储
    function appendServiceLinkEnd(item) {
      if (item.type === 'bpmn:SequenceFlow' && item.suitable === undefined) {
        item.suitable = bpmnStore.getLinkAppendServiceLinkEnd()
        if (item.di?.bpmnElement) {
          const documentationObject = bpmnFactory.create('bpmn:Documentation')
          documentationObject.text = item.suitable
          item.di.bpmnElement.documentation = [documentationObject]
        }
      }
    }

    // 返回需要的组件
    return {
      'create.general-education-compulsory-course': {
        group: 'model',
        //控制操作栏中元素的颜色
        className: 'bpmn-icon-task general-education-compulsory-course',
        //控制操作栏中元素的提示文字
        title: translate('通识必修课'),
        action: {
          //控制操作栏中元素的各种函数
          click: appendServiceTaskStart(General_Education_Compulsory_Course),
          dragstart: appendServiceTaskStart(General_Education_Compulsory_Course)
        }
      },
      'create.subject-based-course': {
        group: 'model',
        className: 'bpmn-icon-task subject-based-course',
        title: translate('学科基础课'),
        action: {
          click: appendServiceTaskStart(Subject_Based_Course),
          dragstart: appendServiceTaskStart(Subject_Based_Course)
        }
      },
      'create.professional-basic-compulsory-course': {
        group: 'model',
        className: 'bpmn-icon-task professional-basic-compulsory-course',
        title: translate('专业基础必修课'),
        action: {
          click: appendServiceTaskStart(Professional_Basic_Compulsory_Course),
          dragstart: appendServiceTaskStart(Professional_Basic_Compulsory_Course)
        }
      },
      'create.practice-section': {
        group: 'model',
        className: 'bpmn-icon-task practice-section',
        title: translate('事件部分'),
        action: {
          click: appendServiceTaskStart(Practice_Section),
          dragstart: appendServiceTaskStart(Practice_Section)
        }
      },
      'create.strong-link': {
        group: 'activity',
        className: 'bpmn-icon-connection-multi strong-link',
        title: translate('强连接'),
        action: {
          click: appendServiceLinkStart(Strong_Link),
          dragstart: appendServiceLinkStart(Strong_Link),
          drag: connect.move,
          dragend: appendServiceLinkEnd(arguments[0])
        }
      },
      'create.week-link': {
        group: 'activity',
        className: 'bpmn-icon-connection-multi week-link',
        title: translate('弱连接'),
        action: {
          //控制线段开始时,去进行一些自定义操作
          click: appendServiceLinkStart(Week_Link),
          dragstart: appendServiceLinkStart(Week_Link),
          //调用原生方法,做成原生一样的效果
          drag: connect.move,
          //控制线段结束,取出相关信息,并在渲染组件中,将相关信息渲染
          dragend: appendServiceLinkEnd(arguments[0])
        }
      },
      'create.delete': {
        group: 'edit',
        className: 'icon-custom bpmn-icon-trash',
        title: translate('删除'),
        action: {
          click: () => {
            //删除对应的元素,你可以在此处处理,如添加二次确认框
            modeling.removeElements([element])
          }
        }
      },
      'create.edit': {
        group: 'edit',
        className: 'icon-custom bpmn-icon-screw-wrench',
        title: translate('编辑'),
        action: {
          click: () => {
            //打开编辑弹出,去重写图像大小
            bpmnStore.bpmnObjectInformation.open(element)
          }
        }
      }
    }
  }
}

CustomContextPad.$inject = [
  'bpmnFactory',
  'contextPad',
  'create',
  'elementFactory',
  'translate',
  'modeling',
  'globalConnect',
  'connect'
]

 注:作者不知道如何将起点元素和终点元素的链接,换为自定义的链接,或者说我所写的项目也并没有提出这样的要求,而网上找到的解决方案为修改源文件,本人才疏学浅,如有大佬也望能够沟通斧正。

渲染组件的自定义

src\utils\bpmn\palette\CustomRenderer.js

import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer'
import { itemColor, itemText, itemClass } from './Item'

import {
  attr as svgAttr
} from 'tiny-svg'

import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil'

import { isNil } from 'min-dash'

const HIGH_PRIORITY = 1500

export default class CustomRenderer extends BaseRenderer {
  constructor(eventBus, bpmnRenderer) {
    super(eventBus, HIGH_PRIORITY)

    this.bpmnRenderer = bpmnRenderer
    this.isShow = false
  }

  canRender(element) {
    return !element.labelTarget
  }

  //绘画普通图像
  drawShape(parentNode, element) {
    const shape = this.bpmnRenderer.drawShape(parentNode, element)
    const suitabilityScoreBase = this.getSuitabilityScore(element)
    const suitabilityScore = this.getText(suitabilityScoreBase)

    //从document中取出信息,方便于渲染颜色
    if (
      element.di?.bpmnElement?.documentation &&
      element.di?.bpmnElement?.documentation.length > 0
    ) {
      svgAttr(shape, {
        fill: this.getColor(element.di?.bpmnElement?.documentation[0].text),
        rx: 0,
        ry: 0,
        height: element.height,
        width: element.width
      })
    } else if (!isNil(suitabilityScore)) {
      svgAttr(shape, {
        fill: this.getColor(suitabilityScoreBase),
        rx: 0,
        ry: 0,
        height: 40
      })
    }

    return shape
  }

  getShapePath(shape) {
    return this.bpmnRenderer.getShapePath(shape)
  }

  getSuitabilityScore(element) {
    const businessObject = getBusinessObject(element)

    const { suitable } = businessObject

    return Number.isFinite(suitable) ? suitable : suitable
  }

  getColor(suitabilityScore) {
    return itemColor[suitabilityScore]
  }

  getText(suitabilityScore) {
    return itemText[suitabilityScore]
  }

  getClass(suitabilityScore) {
    return itemClass[suitabilityScore]
  }

  //绘画连线图案
  drawConnection(parentNode, element, number) {
    const connection = this.bpmnRenderer.drawConnection(parentNode, element)

    if (isNaN(number)) {
      number = 0
    }

    //控制图像渲染此处,以防数字太大而导致一直渲染
    //由于本函数渲染通过全局Store去存储并获取信息,所以使用定时器并结合这种方式,以防驻留在内存中,导致卡顿
    //若有更好方式解决,请斧正,十分感谢
    if (number >= 12) {
      element.suitable = ''
      return connection
    }

    if (element.suitable) {
      svgAttr(connection, {
        stroke: this.getColor(element.suitable)
      })

      this.isShow = true
    } else if (element.di?.bpmnElement?.documentation) {
      svgAttr(connection, {
        stroke: this.getColor(element.di?.bpmnElement?.documentation[0]?.text)
      })

      this.isShow = true
    } else {
      if (this.isShow) {
        this.isShow = false
        return connection
      }
      setTimeout(() => {
        number++
        this.drawConnection(parentNode, element, number)
      }, 100)
    }

    return connection
  }
}

CustomRenderer.$inject = ['eventBus', 'bpmnRenderer']

封装组件

src\components\teacher\index\auxiliaryFunctions\children\course_topology_page.vue

<script setup>
import { ref, onMounted } from 'vue'
import Modeler from 'bpmn-js/lib/Modeler'
import customModule from '@/utils/bpmn/palette'
/** 本处导入自己封装的请求文件,并修改下列请求相关内容 */
import instance from '@/utils/request.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-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import 'bpmn-js-properties-panel/dist/assets/element-templates.css'
import 'bpmn-js-properties-panel/dist/assets/properties-panel.css'

import { customTranslate } from '@/utils/bpmn/tanslate/translations'
import { useBpmnStore } from '@/stores'
import bpmn_edit_dialog from '@/components/dialog/bpmn_edit_dialog.vue'

const bpmnStore = useBpmnStore()

const canvas = ref(null)
const properties = ref(null)
const modeler = ref(null)
const elementRegistry = ref(null)

onMounted(() => {
  initCurrentBpmn()
})

//初始化BPMN内容,此处从后端获取,若需要改为从前端获取,请自行修改
const initCurrentBpmn = async () => {
  if (modeler.value) {
    //清空相关内容,以防多次渲染bpmn,造成多个bpmn页面共存
    modeler.value.clear()
  } else {
    //创建新对象,去渲染相关内容
    modeler.value = new Modeler({
      container: canvas.value,
      propertiesPanel: {
        parent: properties.value
      },
      additionalModules: [
        customModule,
        {
          translate: ['value', customTranslate]
        }
      ]
    })
  }

  let bpmnXML = ''
  try {
    await instance
      .get('/api/CourseTopology/get', {
        grade: bpmnStore.currentGrade,
        majorId: bpmnStore.currentMajorId
      })
      .then((res) => {
        if (res.data?.xmlJsonString) {
          //获取后端数据,去渲染图像
          bpmnXML = res.data.xmlJsonString
        }
      })
      .catch((err) => {
        console.log(err)
      })
    // ...
  } catch (err) {
    // err...
  }
  await modeler.value.importXML(bpmnXML)

  elementRegistry.value = modeler.value.get('elementRegistry')

  //将数据存储到pinia中,为了自定义渲染所需要使用时能够获取
  bpmnStore.setModeler(modeler.value, elementRegistry.value)
}

const updateCourseTopology = () => {
  const xmlString = modeler.value.saveXML({ format: true })

  xmlString.then((data) => {
    const fileName = 'test.bpmn20.xml'

    const blob = new Blob([data.xml], { type: 'application/xml' })

    const file = new File([blob], fileName, { type: 'application/xml' })

    updateCourseTopologyOp(file)
  })
}

const setCurrentTopology = () => {
  bpmnObjectSetCurrentInformation.value.open()
}

//将bpmn转变为svg图像,能够用于后续操作
const saveSVG = async () => {
  const { svg } = await modeler.value.saveSVG({ format: true })

  const dataTrack = 'bpmn'
  const a = document.createElement('a')
  const name = `.${dataTrack}20.svg`
  a.setAttribute('href', `data:application/bpmn20-xml;charset=UTF-8,${encodeURIComponent(svg)}`)
  a.setAttribute('target', '_blank')
  a.setAttribute('dataTrack', `diagram:download-${dataTrack}`)
  a.setAttribute('download', name)
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

const emit = defineEmits([
  'saveSVG',
])

onMounted(() => {
  emit('saveSVG', saveSVG)
})
</script>

<template>
  <div class="content-standrd-content editor">
    <div ref="properties" class="properties"></div>
    <div ref="canvas" class="canvas"></div>
  </div>

  <bpmn_edit_dialog :bpmnObjectInformation="bpmnStore.bpmnObjectInformation">    </bpmn_edit_dialog>
</template>

<style scoped>
@import url('bpmn-js-properties-panel/dist/assets/properties-panel.css');
@import url('@/assets/bpmn.scss');
</style>

调整Task大小弹框

src\components\dialog\bpmn_edit_dialog.vue 

<script setup>
import { ref } from 'vue'
const props = defineProps({ bpmnObjectInformation: Object })

const bpmnObjectInformation = ref(props.bpmnObjectInformation)
</script>

<template>
  <el-dialog
    v-model="bpmnObjectInformation.isOpen"
    :title="bpmnObjectInformation.windowName"
    style="padding: 16px; width: 500px"
  >
    <el-form :model="bpmnObjectInformation" style="text-align: center; margin-top: 10px">
      <el-form-item label="宽度" label-width="80px">
        <el-input v-model="bpmnObjectInformation.baseWidth" autocomplete="off" />
      </el-form-item>
      <el-form-item label="高度" label-width="80px">
        <el-input v-model="bpmnObjectInformation.baseHeight" autocomplete="off" />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="bpmnObjectInformation.close()">取消</el-button>
        <el-button type="primary" @click="bpmnObjectInformation.resetItem()"> 确认 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

总结

        这次是我第一次使用CSDN所作的笔记,网上大多数的教程大多操作繁琐,并且希望一步能过够完整了解BPMN。而我作为一个初学者,站在我的角度上,我希望有一个入门的教程,使得我首先能够快速的入手BPMN,并能够从中获取其基本使用。故出此笔记,如果能给你帮助,那么我十分荣幸,若做得不到位,请斧正而非人身攻击。

        本文章为BPMN-JS在VUE3中的入门应用,并非深入剖析,主要做到BPMN设置其元素改变元素颜色及其大小。并能够将BPMN给最终导出为SVG图标,进一步处理。

        关于后端与前端交互问题,能够解决,由于前端将数据写入document中,可供后端进行操作并且存储,而也能有后端填入相关字段,使得前端渲染出不同的颜色及大小。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/10148.html
标签
评论
发布的文章

用点jquery实现的登录页面

2024-06-06 00:06:07

echarts-锥型柱状图

2024-06-06 00:06:05

echarts的使用

2024-06-06 00:06:00

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!