Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Report]: 自定义vue节点时,拖拽创建节点,mounted执行两次 #2093

Open
chenshitz opened this issue Feb 27, 2025 · 0 comments
Labels
bug Something isn't working

Comments

@chenshitz
Copy link

发生了什么?

代码如下

<template>
  <el-card header="Graph">
    <el-divider content-position="left">节点面板</el-divider>
    <div class="flex-wrapper">
      <div class="circle" @mousedown="handleDragCircle" />
      <div class="rect" @mousedown="handleDragRect" />
      <div class="text" @mousedown="handleDragText">自定义vue节点</div>
    </div>
    <el-divider />
    <div ref="containerRef" id="graph" class="viewport"></div>
    <TeleportContainer :flow-id="flowId" />
  </el-card>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import LogicFlow from '@logicflow/core'
import { register, getTeleport } from '@logicflow/vue-node-registry'
import '@logicflow/core/es/index.css'

import ProgressNode from '@/components/LFElements/ProgressNode.vue'

import { DynamicGroup, dynamicGroup, DynamicGroupNodeModel, SelectionSelect } from '@logicflow/extension'
import '@logicflow/extension/lib/style/index.css'

const lfRef = ref<LogicFlow | null>(null)
const containerRef = ref<HTMLDivElement | null>(null)
const flowId = ref('')
const TeleportContainer = getTeleport()

LogicFlow.use(SelectionSelect)

onMounted(() => {
  if (containerRef.value) {
    const lf = new LogicFlow({
      container: containerRef.value,
      grid: true,
      allowResize: true,
      stopMoveGraph: true,
      plugins: [DynamicGroup]
    })
    lf.register({
      type: 'GroupNode',
      model: CustomGroupModel,
      view: CustomGroup
    })
    register(
      {
        type: 'custom-vue-node',
        component: ProgressNode
      },
      lf
    )
    lf.render({})
    
    lf.openSelectionSelect()

    lfRef.value = lf
  }
})

const handleDragRect = () => {
  lfRef?.value?.dnd.startDrag({
    type: 'GroupNode'
  })
}
const handleDragCircle = () => {
  lfRef?.value?.dnd.startDrag({
    type: 'circle',
    r: 25
  })
}
const handleDragText = () => {
  lfRef?.value?.dnd.startDrag({
    type: 'custom-vue-node'
  })
}

class CustomGroup extends dynamicGroup.view {}

class CustomGroupModel extends DynamicGroupNodeModel {
  initNodeData(data: any) {
    super.initNodeData(data)
    // data.properties = {
    //   collapsible: false
    // }
  }
}
</script>

<style>
.flex-wrapper {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.viewport {
  height: 350px;
  position: relative;
  overflow: hidden;
}

.el-button + .el-button {
  margin-left: 0;
}

*:focus {
  outline: none;
}

.rect {
  width: 50px;
  height: 50px;
  background: #fff;
  border: 2px solid #000;
}

.circle {
  width: 50px;
  height: 50px;
  background: #fff;
  border: 2px solid #000;
  border-radius: 50%;
}

.uml-wrapper {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  background: rgb(255 242 204);
  border: 1px solid rgb(214 182 86);
  border-radius: 10px;
}

.uml-head {
  font-weight: bold;
  font-size: 16px;
  line-height: 30px;
  text-align: center;
}

.uml-body {
  padding: 5px 10px;
  font-size: 12px;
  border-top: 1px solid rgb(214 182 86);
  border-bottom: 1px solid rgb(214 182 86);
}

.uml-footer {
  padding: 5px 10px;
  font-size: 14px;
}

/* 输入框字体大小和设置的大小保持一致,自动换行输入和展示保持一致 */

.lf-text-input {
  font-size: 12px;
}

.buttons {
  position: absolute;
  z-index: 1;
}

.button-list {
  display: flex;
  align-items: center;
}
</style>

自定义vue组件如下

<template>
  <el-progress type="dashboard" :percentage="percentage" :width="80">
    <template #default="{ percentage }">
      <span class="percentage-value">{{ percentage }}%</span>
    </template>
  </el-progress>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { EventType } from '@logicflow/core'
import { vueNodesMap } from '@logicflow/vue-node-registry'

export default defineComponent({
  name: 'ProgressNode',
  inject: ['getNode', 'getGraph'],
  data() {
    return {
      percentage: 80
    }
  },
  mounted() {
    console.log('------')
    const node = (this as any).getNode()
    const graph = (this as any).getGraph()
    graph.eventCenter.on(EventType.NODE_PROPERTIES_CHANGE, (eventData: any) => {
      const keys = eventData.keys as string[]
      const content = vueNodesMap[node.type]
      if (content && eventData.id === node.id) {
        const { effect } = content

        // 如果没有定义 effect,则默认更新;如果定义了 effect,则只有在 effect 中的属性发生变化时才更新
        if (!effect || keys.some((key) => effect.includes(key))) {
          console.log('eventData --->>>', eventData)
          this.percentage = eventData.properties?.progress || 0
        }
      }
    })
  }
})
</script>

Image

这会造成 graph.eventCenter.on(EventType.NODE_PROPERTIES_CHANGE, (eventData: any) =>{}). 执行两次 有什么办法能解决吗

logicflow/core版本

2.0.11

logicflow/extension版本

2.0.15

logicflow/engine版本

No response

浏览器&环境

No response

@chenshitz chenshitz added the bug Something isn't working label Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant