From eb26deff7257e13f569cafec5cddbf14a200ac3d Mon Sep 17 00:00:00 2001 From: rookie4show Date: Sat, 14 Feb 2026 23:47:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=AE=80=E5=8C=96=20TextNode=20?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=8C=E5=AE=8C=E5=85=A8=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=20LogicFlow=20=E5=8E=9F=E7=94=9F=E6=96=87=E6=9C=AC=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除自定义文本编辑逻辑,交由 LogicFlow 和 TextNodeModel 处理 - TextNode.vue 简化为空容器,LogicFlow 自动渲染文本内容 - 保留 TextNodeModel.ts 用于配置文本样式和编辑行为 - 采用模型-视图分离架构,符合 LogicFlow 设计模式 --- src/components/flow/ComponentsPanel.vue | 4 +- src/components/flow/FlowEditor.vue | 23 +++++- src/components/flow/nodes/common/TextNode.vue | 75 +++++++------------ .../flow/nodes/common/TextNodeModel.ts | 37 +++++++++ src/components/flow/panels/TextPanel.vue | 10 ++- 5 files changed, 95 insertions(+), 54 deletions(-) create mode 100644 src/components/flow/nodes/common/TextNodeModel.ts diff --git a/src/components/flow/ComponentsPanel.vue b/src/components/flow/ComponentsPanel.vue index 285d147..1d497ae 100644 --- a/src/components/flow/ComponentsPanel.vue +++ b/src/components/flow/ComponentsPanel.vue @@ -45,9 +45,9 @@ const componentGroups = [ id: 'text', name: '文字编辑框', type: 'textNode', - description: '可编辑富文本的节点', + description: '可编辑文本的节点', data: { - html: '
双击右侧可编辑文字
', + text: '双击编辑文字', width: 200, height: 120 } diff --git a/src/components/flow/FlowEditor.vue b/src/components/flow/FlowEditor.vue index eea842d..748ad80 100644 --- a/src/components/flow/FlowEditor.vue +++ b/src/components/flow/FlowEditor.vue @@ -74,7 +74,8 @@ import YuhunSelectNode from './nodes/yys/YuhunSelectNode.vue'; import PropertySelectNode from './nodes/yys/PropertySelectNode.vue'; import ImageNode from './nodes/common/ImageNode.vue'; import AssetSelectorNode from './nodes/common/AssetSelectorNode.vue'; -// import TextNode from './nodes/common/TextNode.vue'; +import TextNode from './nodes/common/TextNode.vue'; +import TextNodeModel from './nodes/common/TextNodeModel'; import PropertyPanel from './PropertyPanel.vue'; import { useGlobalMessage } from '@/ts/useGlobalMessage'; import { setLogicFlowInstance, destroyLogicFlowInstance } from '@/ts/useLogicFlow'; @@ -312,7 +313,7 @@ function bringForward(nodeId?: string) { if (!targetId) return; const currentNode = lfInstance.getNodeModelById(targetId); - if (!currentNode) return; + if (!currentNode) return;t const currentZIndex = currentNode.zIndex; currentNode.setZIndex(currentZIndex + 1); @@ -662,7 +663,7 @@ function registerNodes(lfInstance: LogicFlow) { register({ type: 'imageNode', component: ImageNode }, lfInstance); register({ type: 'assetSelector', component: AssetSelectorNode }, lfInstance); - // register({ type: 'textNode', component: TextNode }, lfInstance); + register({ type: 'textNode', component: TextNode, model: TextNodeModel }, lfInstance); } // 初始化 LogicFlow @@ -677,6 +678,22 @@ onMounted(() => { keyboard: { enabled: true }, + style: { + text: { + color: '#333333', + fontSize: 14, + background: { + fill: '#ffffff', + stroke: '#dcdfe6', + strokeWidth: 1, + radius: 4 + } + }, + nodeText: { + color: '#333333', + fontSize: 14 + } + }, plugins: [Menu, Label, Snapshot, SelectionSelect, MiniMap, Control], pluginsOptions: { label: { diff --git a/src/components/flow/nodes/common/TextNode.vue b/src/components/flow/nodes/common/TextNode.vue index c2d1703..9afe0b9 100644 --- a/src/components/flow/nodes/common/TextNode.vue +++ b/src/components/flow/nodes/common/TextNode.vue @@ -1,51 +1,30 @@ - - - - - + - - - - - + - - - +--> \ No newline at end of file +.text-content:focus { + background: rgba(64, 158, 255, 0.1); + border-radius: 2px; +} + diff --git a/src/components/flow/nodes/common/TextNodeModel.ts b/src/components/flow/nodes/common/TextNodeModel.ts new file mode 100644 index 0000000..0fe91c0 --- /dev/null +++ b/src/components/flow/nodes/common/TextNodeModel.ts @@ -0,0 +1,37 @@ +import { HtmlNodeModel } from '@logicflow/core'; + +class TextNodeModel extends HtmlNodeModel { + initNodeData(data: any) { + super.initNodeData(data); + // 启用文本编辑功能,支持双击编辑 + this.text.editable = true; + this.text.draggable = false; + + // 如果有 text 属性,设置为文本内容 + if (data.properties?.text) { + this.text.value = data.properties.text; + } + } + + setAttributes() { + // 设置默认尺寸 + this.width = 200; + this.height = 120; + } + + // 自定义文本样式 + getTextStyle() { + const style = super.getTextStyle(); + style.fontSize = 14; + style.color = '#333'; + return style; + } + + // 当文本被编辑后,同步到 properties + updateText(value: string) { + super.updateText(value); + this.setProperty('text', value); + } +} + +export default TextNodeModel; diff --git a/src/components/flow/panels/TextPanel.vue b/src/components/flow/panels/TextPanel.vue index 3d2a6e2..1d17be6 100644 --- a/src/components/flow/panels/TextPanel.vue +++ b/src/components/flow/panels/TextPanel.vue @@ -8,7 +8,15 @@ const props = defineProps<{
文本节点
-
文本编辑器待实现,当前节点内容:{{ props.node?.properties?.text?.content || '未设置' }}
+ +
+ {{ props.node?.properties?.text || '未设置' }} +
+
+
+
+ 💡 提示:双击画布中的节点即可编辑文字 +