hookehuyr

自定义vue节点

1 +<!--
2 + * @Date: 2025-03-11 17:25:14
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-11 18:30:47
5 + * @FilePath: /logic-flow2/src/views/node-vue/ProgressNode.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <el-progress type="dashboard" :percentage="percentage" :width="80">
10 + <template #default="{ percentage }">
11 + <span class="percentage-value">{{ percentage }}%</span>
12 + </template>
13 + </el-progress>
14 +</template>
15 +
16 +<script setup>
17 +import { ref, inject, onMounted } from "vue";
18 +import { EventType } from "@logicflow/core";
19 +import { vueNodesMap } from "@logicflow/vue-node-registry";
20 +
21 +const percentage = ref(80);
22 +const getNode = inject("getNode");
23 +const getGraph = inject("getGraph");
24 +
25 +onMounted(() => {
26 + const node = getNode();
27 + const graph = getGraph();
28 +
29 + graph.eventCenter.on(EventType.NODE_PROPERTIES_CHANGE, (eventData) => { // 监听节点属性变化事件(NODE_PROPERTIES_CHANGE)
30 + const keys = eventData.keys; // 获取发生变化的属性名列表
31 + const content = vueNodesMap[node.type]; // 从 vueNodesMap 中获取当前节点类型对应的配置信息
32 +
33 + if (content && eventData.id === node.id) { // 确保只处理当前节点的属性变化事件,通过比对事件中的节点 ID 和当前节点的 ID
34 + const { effect } = content; // 从节点配置中获取 effect 配置,effect 定义了哪些属性变化时需要触发更新
35 +
36 + // 如果没有定义 effect,则默认更新;如果定义了 effect,则只有在 effect 中的属性发生变化时才更新
37 + if (!effect || keys.some((key) => effect.includes(key))) {
38 + console.log("eventData --->>>", eventData);
39 + percentage.value = eventData.properties?.progress || 0;
40 + }
41 + }
42 + });
43 +});
44 +</script>
1 +<!--
2 + * @Date: 2025-03-11 17:20:37
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-11 18:15:05
5 + * @FilePath: /logic-flow2/src/views/node-vue/index.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div class="container">
10 + <div ref="containerRef" id="graph" class="flow-container"></div>
11 + </div>
12 + <TeleportContainer :flow-id="flowId" />
13 +</template>
14 +
15 +<script setup>
16 +import { forEach, map, has } from "lodash-es";
17 +import LogicFlow, { ElementState, LogicFlowUtil } from "@logicflow/core";
18 +import { register, getTeleport } from "@logicflow/vue-node-registry";
19 +
20 +import ProgressNode from "./ProgressNode.vue";
21 +
22 +const containerRef = ref(null);
23 +const TeleportContainer = getTeleport();
24 +const flowId = ref("");
25 +
26 +onMounted(() => {
27 + if (containerRef.value) {
28 + const lf = new LogicFlow({
29 + container: containerRef.value,
30 + grid: true,
31 + });
32 +
33 + // 注册自定义 vue 节点
34 + register(
35 + {
36 + type: "custom-vue-node",
37 + component: ProgressNode,
38 + },
39 + lf
40 + );
41 +
42 + lf.on("graph:rendered", ({ graphModel }) => {
43 + flowId.value = graphModel?.flowId || "";
44 + });
45 +
46 + // 注册事件
47 + lf.render({});
48 + const node1 = lf.addNode({
49 + id: "vue-node-1",
50 + type: "custom-vue-node",
51 + x: 80,
52 + y: 80,
53 + properties: {
54 + progress: 60,
55 + width: 80,
56 + height: 80,
57 + },
58 + });
59 + console.log("node1 --->>>", node1);
60 +
61 + const node2 = lf.addNode({
62 + id: "vue-node-2",
63 + type: "custom-vue-node",
64 + x: 360,
65 + y: 80,
66 + properties: {
67 + progress: 60,
68 + width: 80,
69 + height: 80,
70 + },
71 + });
72 +
73 + // setInterval(() => {
74 + // const { properties } = node2.getData();
75 + // console.log("properties.progress --->>>", properties?.progress);
76 + // if (has(properties, "progress")) {
77 + // const progress = properties?.progress;
78 + // node2.setProperty("progress", (progress + 10) % 100);
79 + // }
80 + // }, 2000);
81 +
82 + setTimeout(() => {
83 + const { properties } = node2.getData();
84 + console.log("properties.progress --->>>", properties?.progress);
85 + if (has(properties, "progress")) {
86 + const progress = properties?.progress;
87 + node2.setProperty("progress", (progress + 10) % 100);
88 + }
89 + }, 2000);
90 + }
91 +});
92 +</script>
93 +
94 +<style scoped>
95 +.container {
96 + width: 100vw;
97 + height: 100vh;
98 + display: flex;
99 + flex-direction: column;
100 +}
101 +
102 +.flow-container {
103 + flex: 1;
104 + width: 100%;
105 + height: 100%;
106 +}
107 +</style>