安庆市中国白事服务网

Vue3使用LogicFlow更新节点名称的方法

2026-03-31 18:13:02 浏览次数:0
详细信息

1. 基础方法:使用 setProperties 或 updateData

<template>
  <div>
    <div id="container" ref="container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import LogicFlow from '@logicflow/core'
import '@logicflow/core/dist/style/index.css'

const container = ref(null)
let lf = null

onMounted(() => {
  // 初始化 LogicFlow
  lf = new LogicFlow({
    container: container.value,
    grid: true,
  })

  lf.render({
    nodes: [
      {
        id: 'node1',
        type: 'rect',
        x: 100,
        y: 100,
        text: '初始名称',
        properties: {
          name: '节点1'
        }
      }
    ]
  })

  // 更新节点名称的方法
  updateNodeName()
})

// 方法1:使用 setProperties
const updateNodeName1 = () => {
  const nodeModel = lf.getNodeModelById('node1')

  // 方式1:更新 properties
  nodeModel.setProperties({
    name: '新节点名称'
  })

  // 更新显示的文本
  lf.updateText('node1', '新节点名称')
}

// 方法2:使用 updateData
const updateNodeName2 = () => {
  const nodeData = lf.getNodeDataById('node1')

  nodeData.text = '新节点名称'
  nodeData.properties = {
    ...nodeData.properties,
    name: '新节点名称'
  }

  lf.setNodeData('node1', nodeData)
}
</script>

2. 自定义节点支持名称编辑

<template>
  <div>
    <div id="container" ref="container"></div>
    <button @click="startEdit">编辑名称</button>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import LogicFlow from '@logicflow/core'
import { RectNode, RectNodeModel } from '@logicflow/core'
import '@logicflow/core/dist/style/index.css'

// 自定义可编辑节点
class EditableRectModel extends RectNodeModel {
  setAttributes() {
    super.setAttributes()
    this.text.editable = true // 允许文本编辑
  }
}

const container = ref(null)
let lf = null

onMounted(() => {
  lf = new LogicFlow({
    container: container.value,
    grid: true,
  })

  // 注册自定义节点
  lf.register({
    type: 'editable-rect',
    view: RectNode,
    model: EditableRectModel,
  })

  lf.render({
    nodes: [
      {
        id: 'node1',
        type: 'editable-rect',
        x: 100,
        y: 100,
        text: '可编辑节点',
      }
    ]
  })

  // 监听文本编辑完成事件
  lf.on('node:dbclick', ({ data }) => {
    console.log('节点双击:', data)
  })

  lf.on('text:update', ({ data }) => {
    console.log('文本更新:', data)
    // 在这里可以同步更新节点的 properties
    const nodeModel = lf.getNodeModelById(data.id)
    nodeModel.setProperties({
      name: data.text
    })
  })
})

// 触发编辑
const startEdit = () => {
  lf.selectElementById('node1')
  lf.editText('node1')
}
</script>

3. 通过外部输入框更新

<template>
  <div class="container">
    <div class="controls">
      <input v-model="nodeName" placeholder="输入节点名称" />
      <button @click="updateSelectedNode">更新选中节点</button>
      <button @click="updateAllNodes">更新所有节点</button>
    </div>
    <div id="lf-container" ref="container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import LogicFlow from '@logicflow/core'
import '@logicflow/core/dist/style/index.css'

const container = ref(null)
const nodeName = ref('')
let lf = null

onMounted(() => {
  lf = new LogicFlow({
    container: container.value,
    grid: true,
  })

  lf.render({
    nodes: [
      {
        id: 'node1',
        type: 'rect',
        x: 100,
        y: 100,
        text: '节点1',
        properties: { id: 1, name: '节点1' }
      },
      {
        id: 'node2',
        type: 'circle',
        x: 300,
        y: 100,
        text: '节点2',
        properties: { id: 2, name: '节点2' }
      }
    ]
  })

  // 监听节点选择
  lf.on('selection:selected', ({ data }) => {
    if (data.nodes && data.nodes.length > 0) {
      const nodeId = data.nodes[0]
      const nodeData = lf.getNodeDataById(nodeId)
      nodeName.value = nodeData.text || ''
    }
  })
})

// 更新选中节点的名称
const updateSelectedNode = () => {
  const selectedNodes = lf.getSelectElements()

  if (selectedNodes.nodes && selectedNodes.nodes.length > 0) {
    const nodeId = selectedNodes.nodes[0]

    // 更新文本
    lf.updateText(nodeId, nodeName.value)

    // 更新 properties
    const nodeModel = lf.getNodeModelById(nodeId)
    nodeModel.setProperties({
      name: nodeName.value,
      updatedAt: new Date().toISOString()
    })

    // 触发自定义事件
    lf.graphModel.eventCenter.emit('custom:node-updated', {
      nodeId,
      newName: nodeName.value
    })
  }
}

// 批量更新所有节点
const updateAllNodes = () => {
  const nodes = lf.getNodes()

  nodes.forEach(node => {
    lf.updateText(node.id, `${nodeName.value}_${node.id}`)

    const nodeModel = lf.getNodeModelById(node.id)
    nodeModel.setProperties({
      name: `${nodeName.value}_${node.id}`,
      batchUpdated: true
    })
  })
}
</script>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.controls {
  padding: 10px;
  background: #f5f5f5;
  border-bottom: 1px solid #ddd;
}

.controls input {
  margin-right: 10px;
  padding: 5px;
}

.controls button {
  margin-right: 10px;
  padding: 5px 10px;
}

#lf-container {
  flex: 1;
  border: 1px solid #ddd;
}
</style>

4. 使用响应式数据绑定

<template>
  <div>
    <div class="editor">
      <div v-for="node in nodes" :key="node.id" class="node-editor">
        <label>节点 {{ node.id }}:</label>
        <input 
          :value="node.text" 
          @input="updateNodeText(node.id, $event.target.value)"
        />
      </div>
    </div>
    <div id="container" ref="container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import LogicFlow from '@logicflow/core'
import '@logicflow/core/dist/style/index.css'

const container = ref(null)
const nodes = ref([])
let lf = null

onMounted(() => {
  lf = new LogicFlow({
    container: container.value,
    grid: true,
  })

  // 初始数据
  const initialNodes = [
    { id: 'node1', type: 'rect', x: 100, y: 100, text: '节点1' },
    { id: 'node2', type: 'rect', x: 300, y: 100, text: '节点2' }
  ]

  lf.render({ nodes: initialNodes })

  // 初始化响应式数据
  nodes.value = lf.getNodes().map(node => ({
    id: node.id,
    text: node.text,
    data: node
  }))

  // 监听 LogicFlow 数据变化
  lf.on('node:update', ({ data }) => {
    const index = nodes.value.findIndex(n => n.id === data.id)
    if (index !== -1) {
      nodes.value[index].text = data.text
    }
  })
})

// 更新节点文本
const updateNodeText = (nodeId, newText) => {
  lf.updateText(nodeId, newText)

  // 更新响应式数据
  const nodeIndex = nodes.value.findIndex(n => n.id === nodeId)
  if (nodeIndex !== -1) {
    nodes.value[nodeIndex].text = newText
  }

  // 同步更新 properties
  const nodeModel = lf.getNodeModelById(nodeId)
  if (nodeModel) {
    nodeModel.setProperties({
      name: newText,
      updatedTime: Date.now()
    })
  }
}
</script>

关键点总结:

核心 API

事件监听

最佳实践

选择哪种方法取决于你的具体需求:

相关推荐