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:
lf.updateText(nodeId, newText) - 更新节点显示文本
nodeModel.setProperties() - 更新节点属性
lf.setNodeData() - 直接设置节点数据
事件监听:
node:dbclick - 节点双击事件
text:update - 文本更新事件
selection:selected - 选中事件
最佳实践:
- 将显示文本和业务属性分开存储
- 使用自定义节点支持编辑
- 保持 LogicFlow 数据和 Vue 响应式数据同步
选择哪种方法取决于你的具体需求:
- 简单更新:使用
updateText + setProperties
- 需要交互编辑:使用自定义可编辑节点
- 复杂业务逻辑:使用外部控制 + 响应式数据绑定