LogicFlow 是一款流程图编辑框架,提供了一系列流程图交互、编辑所必需的功能和简单灵活的节点自定义、插件等拓展机制,方便我们快速在业务系统内满足类流程图的需求。
核心能力
- 可视化模型:通过 LogicFlow 提供的直观可视化界面,用户可以轻松创建、编辑和管理复杂的逻辑流程图。
- 高可定制性:用户可以根据自己的需要定制节点、连接器和样式,创建符合特定用例的定制逻辑流程图。
- 灵活易拓展: 内置提供丰富的插件,用户也可根据自身需求定制复杂插件实现业务需求。
- 自执行引擎: 执行引擎支持浏览器端执行流程图逻辑,为无代码执行提供新思路。
- 数据可转换:支持 LogicFlow 数据与 BPMN、Turbo 等各种后端执行引擎数据结构转换能力。
添加 logic-flow 基础代码
$ npm install @logicflow/core --save
在 App.vue 文件中, 添加 logic-flow 核心代码;
- <script setup lang="ts">
- import { onMounted, ref } from "vue";
- import LogicFlow from "@logicflow/core";
- import "@logicflow/core/es/index.css";
-
- const container = ref();
-
- onMounted(() => {
- const lf = new LogicFlow({
- container: container.value,
- grid: true,
- });
- lf.render();
- });
- </script>
-
- <template>
- <div class="container" ref="container"></div>
- </template>
-
- <style scoped>
- .container {
- width: 100%;
- height: 100%;
- }
- </style>
使用内置拖拽面板
安装 @logicflow/extension 扩展依赖, 先看一下内置拖拽面板如何使用;
npm install @logicflow/extension --save
再次修改 App.vue 文件内容, 导入 DndPanel 对象及扩展所需要的样式模块;
- import { DndPanel } from "@logicflow/extension";
- import "@logicflow/extension/lib/style/index.css";
在实例化 LogicFlow 对象时, 通过选项 plugins 配置 DndPanel 对象;
- const lf = new LogicFlow({
- ...
- plugins: [DndPanel],
- });
在实例化 LogicFlow 对象后, 通过实例对象 lf.extension.dndPanel 中的 setPatternItems 方法设置拖拽面板的内容:
- // icons 是一组图标对象(Base64字符串)
- import { icons } from "./icons";
-
- lf.extension.dndPanel.setPatternItems([
- {
- label: "选区",
- icon: icons.select,
- },
- {
- type: "circle",
- text: "开始",
- label: "开始节点",
- icon: icons.start,
- },
- {
- type: "rect",
- label: "用户任务",
- icon: icons.task,
- },
- {
- type: "rect",
- label: "系统任务",
- icon: icons.task,
- },
- {
- type: "diamond",
- label: "条件判断",
- icon: icons.condition,
- },
- {
- type: "circle",
- text: "结束",
- label: "结束节点",
- icon: icons.end,
- },
- ]);
重新预览效果, 可以看到内置拖拽面板已经生效;

在React中的使用示例(使用CRA搭建开发环境)
package.json
- {
- "name": "logicflow-react",
- "version": "0.1.0",
- "private": true,
- "dependencies": {
- "@logicflow/core": "^2.0.0",
- "@logicflow/extension": "^2.0.0",
- "@testing-library/jest-dom": "^5.17.0",
- "@testing-library/react": "^13.4.0",
- "@testing-library/user-event": "^13.5.0",
- "antd": "^5.20.1",
- "insert-css": "^2.0.0",
- "react": "^18.3.1",
- "react-dom": "^18.3.1",
- "react-scripts": "5.0.1",
- "web-vitals": "^2.1.4"
- },
- "scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
- "eject": "react-scripts eject"
- },
- "eslintConfig": {
- "extends": [
- "react-app",
- "react-app/jest"
- ]
- },
- "browserslist": {
- "production": [
- ">0.2%",
- "not dead",
- "not op_mini all"
- ],
- "development": [
- "last 1 chrome version",
- "last 1 firefox version",
- "last 1 safari version"
- ]
- }
- }
public/index.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8" />
- <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <meta name="theme-color" content="#000000" />
- <meta
- name="description"
- content="Web site created using create-react-app"
- />
- <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
- <title>React App</title>
- <style>
- html, body, #root{
- margin: 0;
- padding: 0;
- height: 100%;
- }
- </style>
- </head>
- <body>
- <noscript>You need to enable JavaScript to run this app.</noscript>
- <div id="root"></div>
- </body>
- </html>
src/index.js
- import ReactDOM from ''react-dom/client'';
- import React, { useEffect, useRef } from "react";
- import { Button } from "antd";
- import LogicFlow from "@logicflow/core";
- import {
- BpmnElement,
- BpmnXmlAdapter,
- Control,
- Menu,
- SelectionSelect,
- DndPanel,
- } from "@logicflow/extension";
- import "@logicflow/core/es/index.css";
- import "@logicflow/extension/lib/style/index.css";
- import insertCss from ''insert-css'';
-
- const root = ReactDOM.createRoot(document.getElementById(''root''));
-
- const App = () => {
- const container = useRef(null);
- const lfRef = useRef(null);
-
- useEffect(() => {
- lfRef.current = new LogicFlow({
- container: container.current,
- stopZoomGraph: true,
- metaKeyMultipleSelected: true,
- grid: true,
- keyboard: {
- enabled: true,
- },
- snapline: true,
- plugins: [
- BpmnElement,
- BpmnXmlAdapter,
- Control,
- Menu,
- SelectionSelect,
- DndPanel,
- ],
- });
-
- lfRef.current.setPatternItems([
- {
- label: "选区",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAOVJREFUOBGtVMENwzAIjKP++2026ETdpv10iy7WFbqFyyW6GBywLCv5gI+Dw2Bluj1znuSjhb99Gkn6QILDY2imo60p8nsnc9bEo3+QJ+AKHfMdZHnl78wyTnyHZD53Zzx73MRSgYvnqgCUHj6gwdck7Zsp1VOrz0Uz8NbKunzAW+Gu4fYW28bUYutYlzSa7B84Fh7d1kjLwhcSdYAYrdkMQVpsBr5XgDGuXwQfQr0y9zwLda+DUYXLaGKdd2ZTtvbolaO87pdo24hP7ov16N0zArH1ur3iwJpXxm+v7oAJNR4JEP8DoAuSFEkYH7cAAAAASUVORK5CYII=",
- callback: () => {
- lfRef.current.openSelectionSelect();
- lfRef.current.once("selection:selected", () => {
- lfRef.current.closeSelectionSelect();
- });
- },
- },
- {
- type: "bpmn:startEvent",
- label: "开始",
- text: "开始",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAnBJREFUOBGdVL1rU1EcPfdGBddmaZLiEhdx1MHZQXApraCzQ7GKLgoRBxMfcRELuihWKcXFRcEWF8HBf0DdDCKYRZpnl7p0svLe9Zzbd29eQhTbC8nv+9zf130AT63jvooOGS8Vf9Nt5zxba7sXQwODfkWpkbjTQfCGUd9gIp3uuPP8bZ946g56dYQvnBg+b1HB8VIQmMFrazKcKSvFW2dQTxJnJdQ77urmXWOMBCmXM2Rke4S7UAW+/8ywwFoewmBps2tu7mbTdp8VMOkIRAkKfrVawalJTtIliclFbaOBqa0M2xImHeVIfd/nKAfVq/LGnPss5Kh00VEdSzfwnBXPUpmykNss4lUI9C1ga+8PNrBD5YeqRY2Zz8PhjooIbfJXjowvQJBqkmEkVnktWhwu2SM7SMx7Cj0N9IC0oQXRo8xwAGzQms+xrB/nNSUWVveI48ayrFGyC2+E2C+aWrZHXvOuz+CiV6iycWe1Rd1Q6+QUG07nb5SbPrL4426d+9E1axKjY3AoRrlEeSQo2Eu0T6BWAAr6COhTcWjRaYfKG5csnvytvUr/WY4rrPMB53Uo7jZRjXaG6/CFfNMaXEu75nG47X+oepU7PKJvvzGDY1YLSKHJrK7vFUwXKkaxwhCW3u+sDFMVrIju54RYYbFKpALZAo7sB6wcKyyrd+aBMryMT2gPyD6GsQoRFkGHr14TthZni9ck0z+Pnmee460mHXbRAypKNy3nuMdrWgVKj8YVV8E7PSzp1BZ9SJnJAsXdryw/h5ctboUVi4AFiCd+lQaYMw5z3LGTBKjLQOeUF35k89f58Vv/tGh+l+PE/wG0rgfIUbZK5AAAAABJRU5ErkJggg==",
- },
- {
- type: "bpmn:userTask",
- label: "用户任务",
- text: "用户任务",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==",
- },
- {
- type: "bpmn:serviceTask",
- label: "系统任务",
- text: "系统任务",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==",
- },
- {
- type: "bpmn:exclusiveGateway",
- label: "条件判断",
- text: "条件判断",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAAHeEJUAAAAABGdBTUEAALGPC/xhBQAAAvVJREFUOBGNVEFrE0EU/mY3bQoiFlOkaUJrQUQoWMGePLX24EH0IIoHKQiCV0G8iE1covgLiqA/QTzVm1JPogc9tIJYFaQtlhQxqYjSpunu+L7JvmUTU3AgmTfvffPNN++9WSA1DO182f6xwILzD5btfAoQmwL5KJEwiQyVbSVZ0IgRyV6PTpIJ81E5ZvqfHQR0HUOBHW4L5Et2kQ6Zf7iAOhTFAA8s0pEP7AXO1uAA52SbqGk6h/6J45LaLhO64ByfcUzM39V7ZiAdS2yCePPEIQYvTUHqM/n7dgQNfBKWPjpF4ISk8q3J4nB11qw6X8l+FsF3EhlkEMfrjIer3wJTLwS2aCNcj4DbGxXTw00JmAuO+Ni6bBxVUCvS5d9aa04+so4pHW5jLTywuXAL7jJ+D06sl82Sgl2JuVBQn498zkc2bGKxULHjCnSMadBKYDYYHAtsby1EQ5lNGrQd4Y3v4Zo0XdGEmDno46yCM9Tk+RiJmUYHS/aXHPNTcjxcbTFna000PFJHIVZ5lFRqRpJWk9/+QtlOUYJj9HG5pVFEU7zqIYDVsw2s+AJaD8wTd2umgSCCyUxgGsS1Y6TBwXQQTFuZaHcd8gAGioE90hlsY+wMcs30RduYtxanjMGal8H5dMW67dmT1JFtYUEe8LiQLRsPZ6IIc7A4J5tqco3T0pnv/4u0kyzrYUq7gASuEyI8VXKvB9Odytv6jS/PNaZBln0nioJG/AVQRZvApOdhjj3Jt8QC8Im09SafwdBdvIpztpxWxpeKCC+EsFdS8DCyuCn2munFpL7ctHKp+Xc5cMybeIyMAN33SPL3ZR9QV1XVwLyzHm6Iv0/yeUuUb7PPlZC4D4HZkeu6dpF4v9j9MreGtMbxMMRLIcjJic9yHi7WQ3yVKzZVWUr5UrViJvn1FfUlwe/KYVfYyWRLSGNu16hR01U9IacajXPei0wx/5BqgInvJN+MMNtNme7ReU9SBbgntovn0kKHpFg7UogZvaZiOue/q1SBo9ktHzQAAAAASUVORK5CYII=",
- },
- {
- type: "bpmn:endEvent",
- label: "结束",
- text: "结束",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC",
- },
- ]);
-
- lfRef.current.render({});
- }, []);
-
- const download = (filename, text) => {
- const element = document.createElement("a");
- element.setAttribute(
- "href",
- "data:text/plain;charset=utf-8," + encodeURIComponent(text)
- );
- element.setAttribute("download", filename);
- element.style.display = "none";
- document.body.appendChild(element);
- element.click();
- document.body.removeChild(element);
- };
-
- const downloadXml = () => {
- const data = lfRef.current.getGraphData();
- download("logic-flow.xml", data);
- };
-
- const uploadXml = (ev) => {
- const file = ev.target.files[0];
- const reader = new FileReader();
- reader.onload = (event) => {
- if (event.target) {
- const xml = event.target.result;
- lfRef.current.render(xml);
- }
- };
- reader.readAsText(file);
- };
-
- return (
- <>
- <div className="explain">
- 点击左下角下载 XML,将文件上传到
- <Button type="link" href="https://demo.bpmn.io/" target="_blank">
- BPMN Demo
- </Button>
- 即可使用
- </div>
- <div id="graph" ref={container}></div>
- <div className="graph-io">
- <span title="下载 XML" onMouseDown={() => downloadXml()}>
- <img
- src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABqUlEQVQ4T92Uv0tbURTHPyevUwc3qUshU/8DBzOYmwiFDlK6dHKwVHBwUKjUoleS4Ku0UkEHB6HSDp1cpHRwSnKz1KH/QaeAS0txcXDy5ciNL5LEF4k/oOBZHvfdcz/33O/53ivccUgvnrFaBAo95ksuFD9/Kf4LMOdCcb4UY9UAVeBWFd5XoHmnaQIKCOm21nnNko7c1LQZSp2IkvsgdT+86PLYoj6KUvzp8sGvIGCiXJLf/v9YQZ9EEd+A4fa8oMFQeVX+dgD9IG8134CvwGMV1morspDkteyyfhTlLXCYgslKKJVW3iUfxlV46Aiw40KZaocaq5+B18BBEDDZqv4CmLO6pnDS7vzxoj48PuWLwEuU7ymY8QsasIXwXGF34AGvfhTlpAUatfo0BRkxVhVwLpRc9/GM1U/AG4WfsT4ZYN2FMp+Q6w1vrgTGt2MW2IgBcy6UzSRdjdX+gH5xdlGf+W9tVfaTYPHG/QN7QbqadQ7MWj0S5ZiIXMuc/QA6YOeXoqrCgNfwqnfvuuxS04fZJd0W4QUweF1CnP9Plb3ae5nu+cDeEMwZu/TFGsleoRIAAAAASUVORK5CYII="
- alt="下载XML"
- />
- </span>
- <span id="upload-xml" title="上传 XML">
- <input
- type="file"
- className="upload"
- onChange={(ev) => uploadXml(ev)}
- />
- <img
- className="upload-img"
- src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABMUlEQVQ4T+XUsUrEQBCA4X8MCD6Cr6DPIOawFiy8gE9ga62BM7D6Aj6CYOHZnaAg6h62Yqed7dmKnUUYmbARDafZwBWCWyWb2W9nZ3cjzLjJjD2iwZVdXbw7lJe2BKLANNcUSOfg+MbJ82/oN7CX64nCVhjgvZNewG6tT+FhPmH9qpBJmqtanwgTVba9k/Pq/etsdRBQhOCRKvfAI7AcYsckbFCyE94HFu+d7P8EVh/XBrpUllwCb8AZMFAlE+EUYbTwSv/iSN5DEu1gmqvNuJkkZGVJZqB3Iqt72jfU8PGBDKNBS9+yvC7kKeAVaP2GGmbPncC6vk1wSt3bl9wYZMv/zPAfgKH4qXfim7ckZlOG3okdk6gWA0ZBjaDpuxwObX3FusB276tyRP1tush/H/wANP7LFUnxl7EAAAAASUVORK5CYII="
- alt="上传XML"
- />
- </span>
- </div>
- </>
- );
- };
-
- root.render(<App></App>);
-
- insertCss(`
- .explain {
- height: 30px;
- }
- #graph {
- width: 100%;
- height: calc(100% - 30px);
- }
- .graph-io {
- position: absolute;
- left: 10px;
- bottom: 10px;
- z-index: 9999;
- background:rgba(255,255,255,0.8);
- box-shadow: 0 1px 4px rgba(0,0,0,.3);
- padding: 10px;
- display: flex;
- }
- .graph-io > span {
- margin: 0 5px;
- cursor: pointer;
- }
- #upload-xml {
- position: relative;
- overflow: hidden;
- display: inline-block;
- cursor: pointer;
- }
- .upload {
- position: absolute;
- z-index: 99;
- left: 0;
- top: 0;
- opacity: 0;
- cursor: pointer;
- }
- .upload::-webkit-file-upload-button {
- cursor: pointer;
- }
- .upload-img {
- width: 26px;
- }
- `);
在Vue3中使用(使用Vite搭建开发环境)
package.json:
- {
- "name": "logicflow",
- "version": "0.0.0",
- "private": true,
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "vite build",
- "preview": "vite preview"
- },
- "dependencies": {
- "@logicflow/core": "^2.0.0",
- "@logicflow/extension": "^2.0.0",
- "vue": "^3.4.29"
- },
- "devDependencies": {
- "@vitejs/plugin-vue": "^5.0.5",
- "unplugin-auto-import": "^0.18.2",
- "unplugin-vue-components": "^0.27.3",
- "vite": "^5.3.1"
- }
- }
src/App.vue:
- <template>
- <div class="root" ref="rootRef"></div>
- <div class="graph"></div>
- <div class="graph-io">
- <span title="下载 XML" @mousedown="downloadXml">
- <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABqUlEQVQ4T92Uv0tbURTHPyevUwc3qUshU/8DBzOYmwiFDlK6dHKwVHBwUKjUoleS4Ku0UkEHB6HSDp1cpHRwSnKz1KH/QaeAS0txcXDy5ciNL5LEF4k/oOBZHvfdcz/33O/53ivccUgvnrFaBAo95ksuFD9/Kf4LMOdCcb4UY9UAVeBWFd5XoHmnaQIKCOm21nnNko7c1LQZSp2IkvsgdT+86PLYoj6KUvzp8sGvIGCiXJLf/v9YQZ9EEd+A4fa8oMFQeVX+dgD9IG8134CvwGMV1morspDkteyyfhTlLXCYgslKKJVW3iUfxlV46Aiw40KZaocaq5+B18BBEDDZqv4CmLO6pnDS7vzxoj48PuWLwEuU7ymY8QsasIXwXGF34AGvfhTlpAUatfo0BRkxVhVwLpRc9/GM1U/AG4WfsT4ZYN2FMp+Q6w1vrgTGt2MW2IgBcy6UzSRdjdX+gH5xdlGf+W9tVfaTYPHG/QN7QbqadQ7MWj0S5ZiIXMuc/QA6YOeXoqrCgNfwqnfvuuxS04fZJd0W4QUweF1CnP9Plb3ae5nu+cDeEMwZu/TFGsleoRIAAAAASUVORK5CYII="
- alt="下载XML" />
- </span>
- <span id="upload-xml" title="上传 XML">
- <input type="file" class="upload" @change="uploadXml" />
- <img class="upload-img"
- src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABMUlEQVQ4T+XUsUrEQBCA4X8MCD6Cr6DPIOawFiy8gE9ga62BM7D6Aj6CYOHZnaAg6h62Yqed7dmKnUUYmbARDafZwBWCWyWb2W9nZ3cjzLjJjD2iwZVdXbw7lJe2BKLANNcUSOfg+MbJ82/oN7CX64nCVhjgvZNewG6tT+FhPmH9qpBJmqtanwgTVba9k/Pq/etsdRBQhOCRKvfAI7AcYsckbFCyE94HFu+d7P8EVh/XBrpUllwCb8AZMFAlE+EUYbTwSv/iSN5DEu1gmqvNuJkkZGVJZqB3Iqt72jfU8PGBDKNBS9+yvC7kKeAVaP2GGmbPncC6vk1wSt3bl9wYZMv/zPAfgKH4qXfim7ckZlOG3okdk6gWA0ZBjaDpuxwObX3FusB276tyRP1tush/H/wANP7LFUnxl7EAAAAASUVORK5CYII="
- alt="上传XML" />
- </span>
- </div>
- </template>
-
- <script setup>
- import { ref, onMounted } from "vue";
- import LogicFlow from "@logicflow/core";
- import {
- BpmnElement,
- BpmnXmlAdapter,
- Control,
- Menu,
- SelectionSelect,
- DndPanel,
- } from "@logicflow/extension";
- import "@logicflow/core/es/index.css";
- import "@logicflow/extension/lib/style/index.css";
-
- const rootRef = ref(null)
- const lfRef = ref(null);
-
- const download = (filename, text) => {
- const element = document.createElement("a");
- element.setAttribute(
- "href",
- "data:text/plain;charset=utf-8," + encodeURIComponent(text)
- );
- element.setAttribute("download", filename);
- element.style.display = "none";
- document.body.appendChild(element);
- element.click();
- document.body.removeChild(element);
- };
-
- const downloadXml = () => {
- const data = lfRef.value.getGraphData();
- download("logic-flow.xml", data);
- };
-
- const uploadXml = (ev) => {
- const file = ev.target.files[0];
- const reader = new FileReader();
- reader.onload = (event) => {
- if (event.target) {
- const xml = event.target.result;
- lfRef.value.render(xml);
- }
- };
- reader.readAsText(file);
- };
-
- onMounted(() => {
- lfRef.value = new LogicFlow({
- container: rootRef.value,
- stopZoomGraph: true,
- metaKeyMultipleSelected: true,
- grid: true,
- keyboard: {
- enabled: true,
- },
- snapline: true,
- plugins: [
- BpmnElement,
- BpmnXmlAdapter,
- Control,
- Menu,
- SelectionSelect,
- DndPanel,
- ],
- });
-
- lfRef.value.setPatternItems([
- {
- label: "选区",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAOVJREFUOBGtVMENwzAIjKP++2026ETdpv10iy7WFbqFyyW6GBywLCv5gI+Dw2Bluj1znuSjhb99Gkn6QILDY2imo60p8nsnc9bEo3+QJ+AKHfMdZHnl78wyTnyHZD53Zzx73MRSgYvnqgCUHj6gwdck7Zsp1VOrz0Uz8NbKunzAW+Gu4fYW28bUYutYlzSa7B84Fh7d1kjLwhcSdYAYrdkMQVpsBr5XgDGuXwQfQr0y9zwLda+DUYXLaGKdd2ZTtvbolaO87pdo24hP7ov16N0zArH1ur3iwJpXxm+v7oAJNR4JEP8DoAuSFEkYH7cAAAAASUVORK5CYII=",
- callback: () => {
- lfRef.current.openSelectionSelect();
- lfRef.current.once("selection:selected", () => {
- lfRef.current.closeSelectionSelect();
- });
- },
- },
- {
- type: "bpmn:startEvent",
- label: "开始",
- text: "开始",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAnBJREFUOBGdVL1rU1EcPfdGBddmaZLiEhdx1MHZQXApraCzQ7GKLgoRBxMfcRELuihWKcXFRcEWF8HBf0DdDCKYRZpnl7p0svLe9Zzbd29eQhTbC8nv+9zf130AT63jvooOGS8Vf9Nt5zxba7sXQwODfkWpkbjTQfCGUd9gIp3uuPP8bZ946g56dYQvnBg+b1HB8VIQmMFrazKcKSvFW2dQTxJnJdQ77urmXWOMBCmXM2Rke4S7UAW+/8ywwFoewmBps2tu7mbTdp8VMOkIRAkKfrVawalJTtIliclFbaOBqa0M2xImHeVIfd/nKAfVq/LGnPss5Kh00VEdSzfwnBXPUpmykNss4lUI9C1ga+8PNrBD5YeqRY2Zz8PhjooIbfJXjowvQJBqkmEkVnktWhwu2SM7SMx7Cj0N9IC0oQXRo8xwAGzQms+xrB/nNSUWVveI48ayrFGyC2+E2C+aWrZHXvOuz+CiV6iycWe1Rd1Q6+QUG07nb5SbPrL4426d+9E1axKjY3AoRrlEeSQo2Eu0T6BWAAr6COhTcWjRaYfKG5csnvytvUr/WY4rrPMB53Uo7jZRjXaG6/CFfNMaXEu75nG47X+oepU7PKJvvzGDY1YLSKHJrK7vFUwXKkaxwhCW3u+sDFMVrIju54RYYbFKpALZAo7sB6wcKyyrd+aBMryMT2gPyD6GsQoRFkGHr14TthZni9ck0z+Pnmee460mHXbRAypKNy3nuMdrWgVKj8YVV8E7PSzp1BZ9SJnJAsXdryw/h5ctboUVi4AFiCd+lQaYMw5z3LGTBKjLQOeUF35k89f58Vv/tGh+l+PE/wG0rgfIUbZK5AAAAABJRU5ErkJggg==",
- },
- {
- type: "bpmn:userTask",
- label: "用户任务",
- text: "用户任务",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==",
- },
- {
- type: "bpmn:serviceTask",
- label: "系统任务",
- text: "系统任务",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==",
- },
- {
- type: "bpmn:exclusiveGateway",
- label: "条件判断",
- text: "条件判断",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAAHeEJUAAAAABGdBTUEAALGPC/xhBQAAAvVJREFUOBGNVEFrE0EU/mY3bQoiFlOkaUJrQUQoWMGePLX24EH0IIoHKQiCV0G8iE1covgLiqA/QTzVm1JPogc9tIJYFaQtlhQxqYjSpunu+L7JvmUTU3AgmTfvffPNN++9WSA1DO182f6xwILzD5btfAoQmwL5KJEwiQyVbSVZ0IgRyV6PTpIJ81E5ZvqfHQR0HUOBHW4L5Et2kQ6Zf7iAOhTFAA8s0pEP7AXO1uAA52SbqGk6h/6J45LaLhO64ByfcUzM39V7ZiAdS2yCePPEIQYvTUHqM/n7dgQNfBKWPjpF4ISk8q3J4nB11qw6X8l+FsF3EhlkEMfrjIer3wJTLwS2aCNcj4DbGxXTw00JmAuO+Ni6bBxVUCvS5d9aa04+so4pHW5jLTywuXAL7jJ+D06sl82Sgl2JuVBQn498zkc2bGKxULHjCnSMadBKYDYYHAtsby1EQ5lNGrQd4Y3v4Zo0XdGEmDno46yCM9Tk+RiJmUYHS/aXHPNTcjxcbTFna000PFJHIVZ5lFRqRpJWk9/+QtlOUYJj9HG5pVFEU7zqIYDVsw2s+AJaD8wTd2umgSCCyUxgGsS1Y6TBwXQQTFuZaHcd8gAGioE90hlsY+wMcs30RduYtxanjMGal8H5dMW67dmT1JFtYUEe8LiQLRsPZ6IIc7A4J5tqco3T0pnv/4u0kyzrYUq7gASuEyI8VXKvB9Odytv6jS/PNaZBln0nioJG/AVQRZvApOdhjj3Jt8QC8Im09SafwdBdvIpztpxWxpeKCC+EsFdS8DCyuCn2munFpL7ctHKp+Xc5cMybeIyMAN33SPL3ZR9QV1XVwLyzHm6Iv0/yeUuUb7PPlZC4D4HZkeu6dpF4v9j9MreGtMbxMMRLIcjJic9yHi7WQ3yVKzZVWUr5UrViJvn1FfUlwe/KYVfYyWRLSGNu16hR01U9IacajXPei0wx/5BqgInvJN+MMNtNme7ReU9SBbgntovn0kKHpFg7UogZvaZiOue/q1SBo9ktHzQAAAAASUVORK5CYII=",
- },
- {
- type: "bpmn:endEvent",
- label: "结束",
- text: "结束",
- icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC",
- },
- ]);
-
- lfRef.value.render({});
- });
- </script>
-
- <style scoped>
- .root {
- width: 100%;
- height: 100%;
- }
-
- .explain {
- height: 30px;
- }
-
- .graph {
- width: 100%;
- height: calc(100% - 30px);
- }
-
- .graph-io {
- position: absolute;
- left: 10px;
- bottom: 10px;
- z-index: 9999;
- background: rgba(255, 255, 255, 0.8);
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
- padding: 10px;
- display: flex;
- }
-
- .graph-io>span {
- margin: 0 5px;
- cursor: pointer;
- }
-
- #upload-xml {
- position: relative;
- overflow: hidden;
- display: inline-block;
- cursor: pointer;
- }
-
- .upload {
- position: absolute;
- z-index: 99;
- left: 0;
- top: 0;
- opacity: 0;
- cursor: pointer;
- }
-
- .upload::-webkit-file-upload-button {
- cursor: pointer;
- }
-
- .upload-img {
- width: 26px;
- }
- </style>
效果:

官网:https://site.logic-flow.cn/
www.hhzai.top