LogicFlow icon indicating copy to clipboard operation
LogicFlow copied to clipboard

[Bug Report]:

Open h-mole opened this issue 1 month ago • 3 comments

发生了什么?

感谢滴滴和LogicFlow团队的卓越贡献,作为一名个人开发者,LogicFlow项目极大的促进了我的开发效率。但我在使用Vue+LogicFlow的时候碰到了一个问题,当使用dnd拖拽面板拖拽添加自定义Vue节点时,会报出如下错误:

teleport.ts:46 
 [Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core 
  at <Anonymous flow-id="" > 
  at <Flowchart onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< 
Proxy(Object) {__v_skip: true}
 > > 
  at <RouterView> 
  at <ElMain class="main-cont main-right" > 
  at <ElContainer> 
  at <ElContainer class="layout-cont" > 
  at <LayoutIndex onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< 
Proxy(Object) {…}
 > > 
  at <RouterView> 
  at <App>

通过检索发现,博文 https://blog.csdn.net/Dejan_yang/article/details/150058984中提到,<template>标签头部的注释会影响vue组件的挂载和销毁,因此删除template的头部注释后,可正常挂载。

错误案例(最小可复现,只关注template头部的注释即可):

<template>
    <!-- <div>aaaaaaaaaaaaaaaaaa</div> -->
     <div>This is test</div>
</template>
<style scoped>
.ping-card {
    max-width: 400px;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: #4285F4;
    padding: 12px 16px;
    margin: -16px -16px 16px -16px;
    border-radius: 4px 4px 0 0;
}

.card-title {
    color: white;
    font-size: 18px;
    font-weight: bold;
}

.header-right {
    display: flex;
    align-items: center;
}

.card-content {
    margin-bottom: 16px;
}

.test-case-info {
    margin-bottom: 12px;
    color: #333;
    font-size: 14px;
}

.test-case-controls {
    display: flex;
    gap: 12px;
    align-items: center;
}

.test-case-select {
    flex: 1;
}

.add-button {
    width: 32px;
    height: 32px;
}

.card-footer {
    border-top: 1px solid #ebeef5;
    padding-top: 16px;
}

.result-content {
    display: flex;
    gap: 16px;
    align-items: center;
    flex-wrap: wrap;
}

.result-item {
    display: flex;
    align-items: center;
    gap: 8px;
}

.result-tag {
    background-color: #e1f5fe;
    color: #0277bd;
    border: none;
}

.result-label {
    color: #666;
    font-size: 14px;
}

.result-value {
    color: #333;
    font-weight: 500;
}

/* Element Plus 样式覆盖 */
:deep(.el-card__body) {
    padding: 16px;
}

:deep(.el-switch__label) {
    color: white;
}

:deep(.el-collapse-item__header) {
    font-size: 14px;
    color: #333;
}

:deep(.el-collapse-item__content) {
    padding: 16px;
}
</style>
<script lang="ts">
import { defineComponent, Ref, ComponentInternalInstance } from 'vue'
import { EventType, h as lfh } from '@logicflow/core'
import { vueNodesMap, VueNodeModel, VueNodeView } from '@logicflow/vue-node-registry'
import { inject, ref } from 'vue'
import { HtmlNode, HtmlNodeModel } from '@logicflow/core'

interface TestCase {
    id: number | string
    name: string
}



const HEAD_OFFSET = 60

export default defineComponent({
    name: 'ProgressNode',
    inject: ['getNode', 'getGraph'],
    data() {
        const { updateMsg, messageContent } = inject('message') as {
            updateMsg: Function;
            messageContent: string
        }
        return {
            percentage: 80,
            message: messageContent,
            updateMsg,
            HEAD_OFFSET,
            isReady: false,
            selectedTestCase: '' as string | number,
            delay: 0,
            testCases: [
                { id: 1, name: '卡片测试用例' }
            ] as TestCase[],
            resizeObserver: null as ResizeObserver | null
        }
    },
    // mounted() {
    //     const node = (this as any).getNode()
    //     const graph = (this as any).getGraph()

    //     // 初始化 ResizeObserver
    //     // this.initResizeObserver();
    // },
    // beforeUnmount() {
    //     console.log('beforeUnmount')
    //     // 清理 ResizeObserver
    //     if (this.resizeObserver) {
    //         this.resizeObserver.disconnect();
    //         this.resizeObserver = null;
    //     }
    // },
    methods: {
        initResizeObserver() {
            // 创建 ResizeObserver 实例
            this.resizeObserver = new ResizeObserver(entries => {
                for (let entry of entries) {
                    const { height } = entry.contentRect;
                    const node = (this as any).getNode();
                    if (node) {
                        node.setProperties({ height: Math.ceil(height) });
                    }
                }
            });

            // 开始观察目标元素
            const pingCard = this.$refs.pingCard as any;
            if (pingCard && pingCard.$el) {
                this.resizeObserver.observe(pingCard.$el);
            }
        }
    }

})

export class CustomNodeModel extends VueNodeModel {
    isShowAnchor: boolean = true

    setAttributes() {
        this.width = 240;
        // 获取节点属性中的高度,如果没有则使用默认值
        const properties = this.getProperties();
        this.height = properties.height || 300;
    }

    getDefaultAnchor() {
        const {
            id,
            x,
            y,
            width,
            height,
            isHovered,
            isSelected,
            properties: { fields, isConnection },
        } = this as any;
        const anchors: Array<{
            x: number;
            y: number;
            id: string;
            edgeAddable?: boolean;
            type: string;
        }> = [];

        this.setIsShowAnchor(true)
        return [
            {
                x: x - width / 2 + 10,
                y: y - height / 2 + HEAD_OFFSET + 0 * 24,
                id: `${id}_left`,
                edgeAddable: false,
                type: 'left',
            },
            {
                x: x + width / 2 - 10,
                y: y - height / 2 + HEAD_OFFSET + 0 * 24,
                id: `${id}_right`,
                type: 'right',
            }
        ]
    }
}

export class CustomNodeView extends VueNodeView {
    getAnchorShape(anchorData: any) {
        const { x, y, type } = anchorData;
        console.log('anchorData --->>>', anchorData);
        return lfh('rect', {
            x: x - 5,
            y: y - 5,
            width: 10,
            height: 10,
            className: `custom-anchor ${type === 'left' ? 'incomming-anchor' : 'outgoing-anchor'}`,
        });
    }
}
</script>

logicflow/core版本

2.2.0-alpha.0

logicflow/extension版本

2.2.0-alpha.0

logicflow/engine版本

No response

浏览器&环境

Chrome

h-mole avatar Dec 08 '25 04:12 h-mole

该 issue 作为 Bug Report 所提供信息的不充分,被暂时关闭了。请修改 issue 以提供最小可复现示例(可以通过以下方式:1. 在任意在线编码平台如 codesanbox 编写示例。将其保存到自己空间,然后贴上链接。2. 在自己 github 中创建一个最简单的示例,然后贴上 github 链接。3. 删除项目中的 node_modules 部分,打包项目,并拖拽到 issue 输入框中上传(或提供远程可下载地址))来重启 issue。

github-actions[bot] avatar Dec 08 '25 04:12 github-actions[bot]

该 issue 作为 Bug Report 所提供信息的不充分,被暂时关闭了。请修改 issue 以提供最小可复现示例(可以通过以下方式:1. 在任意在线编码平台如 codesanbox 编写示例。将其保存到自己空间,然后贴上链接。2. 在自己 github 中创建一个最简单的示例,然后贴上 github 链接。3. 删除项目中的 node_modules 部分,打包项目,并拖拽到 issue 输入框中上传(或提供远程可下载地址))来重启 issue。

github-actions[bot] avatar Dec 08 '25 04:12 github-actions[bot]

感谢你的反馈~ 让我看看这个问题怎么个事🤔 我可能得用你的demo复现一下看看,如果有进展会通过评论同步你

DymoneLewis avatar Dec 09 '25 11:12 DymoneLewis