LogicFlow 自定义可分组拖拽面板
近期有小伙伴在使用 Logic-Flow 流程图编辑框架的时候, 对于如何实现自定义可分组拖拽面板没有找到思路, 在简单沟通过后, 我觉得可以提供一个简单的示例来帮助大家快速了解;
Tip:
- Vue 版本的拖拽面板插件,借助 h 函数将 AntdV 组件库中的 Collapse 组件接入到拖拽面板。
main 分之 src/extension/dnd-panel-vue.ts
- React 版本的拖拽面板插件,借助 createRoot 函数将 ant-design 组件库中的 Collapse 组件接入到拖拽面板,接入难度较 Vue 版本底。
react 分之 src/extension/dnd-panel-react.tsx
效果展示
涉及内容点
- Logic-Flow 入门使用;
- Logic-Flow 内置插件使用;
- WebComponents 介绍;
- Logic-Flow 自定义插件;
简单的需求分析
准备一个基础项目
首先使用 npm create
创建一个基于 vite
最新版本构建的 vue + typescript
项目;
npm create vite@latest lf-dnd-panel
接着删除默认提供的 HelloWorld.vue
组件及其引用, 最终的项目目录结构如下;
lf-dnd-panel ├─ public │ └─ vite.svg ├─ src │ ├─ assets │ │ └─ vue.svg │ ├─ App.vue │ ├─ main.ts │ ├─ style.css │ └─ vite-env.d.ts ├─ README.md ├─ index.html ├─ package-lock.json ├─ package.json ├─ tsconfig.json ├─ tsconfig.node.json └─ vite.config.ts
尝试启动项目, 确保一切正常;
npm run dev
添加 logic-flow
基础代码
首先安装 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/dist/style/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>
同时要将下面的样式覆盖掉 style.css
文件内容;
body { height: 100%; margin: 0; padding: 0; } #app { width: 100%; height: 100%; position: absolute; left: 0; top: 0; }
使用内置拖拽面板
安装 @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, }, ]);
重新预览效果, 可以看到内置拖拽面板已经生效;
自定义可分组拖拽面板
在自定义可分组拖拽面板时, 我选择在 dnd-panel 源码 的基础上搭配 Web Component 组件定制拖拽面板插件.
Web Component
Web Component 浏览器原生支持且可跨前端框架使用的组件开发技术, 哈罗团队利用其开源的 Quarkc 框架所开发的 Quarkd 就是典型的 Web Components 组件库 (Mobile).
我选择使用 Quarkc 对 Quarkd 中 collapse 组件的源码提前开发一个适用于 PC 端的折叠组件.
PS: 折叠组件位于项目 (src/extension/px-collapse.js
) 目录.
获取 dnd-panel 源码
- 在
src
目录下创建extension/dnd-panel.ts
文件; - 复制 dnd-panel 源码 到
extension/dnd-panel.ts
; - 修改
App.vue
中import
语句, 导入extension/dnd-panel.ts
文件;
重写 dnd-panel 插件
安装 collapse
组件的唯一依赖 quarkc
;
npm i quarkc --save
在 extension/dnd-panel
导入 collapse
组件;
// ./extension/dnd-panel.ts import "./px-collapse";
调整 setPatternItems
函数的数据结构, 使其支持 collapse
组件;
type GroupItem = { group: string; items?: ShapeItem[]; }; setPatternItems(groupList: GroupItem[]) { this.groupList = groupList; // 支持渲染后重新设置拖拽面板 if (this.domContainer) { this.render(this.lf, this.domContainer); } }
使用原生 DOM 操作的方式创建 collapse
元素;
private createCollapse(groupName: string): HTMLElement { const collapse = document.createElement("px-collapse"); collapse.setAttribute("title", groupName); return collapse; }
最后调整 render
方法, 将每一组的节点都添加到对应的 collapse
组件中;
render(_lf: LogicFlow, domContainer: HTMLElement) { ... this.panelEl = document.createElement("div"); this.panelEl.className = "lf-dndpanel"; this.groupList.forEach((groupItem) => { const collapse = this.createCollapse(groupItem.group); const container = document.createElement("div"); container.className = "collapse-container"; // 第一步: collapse 组件添加 div 内容容器, 并设置 className, 方便调整样式; collapse.appendChild(container); groupItem?.items && groupItem.items.forEach((shapeItem) => { // 第二步: 循环每组中的 items 数组, 创建 DndItem 元素并添加到 collapse 组件; container.appendChild(this.createDndItem(shapeItem)); }); // 第三步: 将每一个 collapse 组件添加到面板中; this.panelEl.appendChild(collapse); }); domContainer.appendChild(this.panelEl); this.domContainer = domContainer; }
当然还要 setPatternItems
方法的数据结构变更后还有更新其数据;
[ { group: "功能节点", items: [ { label: "选区", icon: icons.select, }, ], }, { group: "起始节点", items: [ { type: "circle", text: "开始", label: "开始节点", icon: icons.start, }, { type: "circle", text: "结束", label: "结束节点", icon: icons.end, group: "GruopB", }, ], }, { group: "任务节点", items: [ { type: "rect", label: "用户任务", icon: icons.task }, { type: "rect", label: "系统任务", icon: icons.task, group: "GruopC" }, ], }, { group: "条件节点", items: [{ type: "diamond", label: "条件判断", icon: icons.condition }], }, ];
最终的预览效果如下:
总结
在本次的体验中, 我们学习了 LogicFlow 的拖拽面板插件的使用, 也了解了如何自定义拖拽面板的样式和内容, 同时还结合的了 Quarkc 开发的 Web Component 组件, 从而轻松的实现了一个可分组的拖拽面板插件.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了