在图建模应用中,节点除了展示信息,还需要具备交互能力(创建、编辑、联动等)。借助 @antv/x6-vue-shape ,我们可以将 Vue 组件直接作为 X6 的节点形状,实现高可维护的 UI 与逻辑解耦。
核心目标
- 使用 Vue SFC 作为节点形状,保持良好可维护性
- 通过 Teleport 容器将节点挂载到画布
- 在节点内触发业务事件,交由统一事件管理器分发
组件结构
vue
<template>
<div class="md-custom-node">
<div class="md-custom-node__parent" v-if="nodeData.level == 1">
<div class="md-custom-node__parent-title">{{ nodeData.modelName }}</div>
<div v-if="!nodeChildren" class="md-custom-node__create-btn" @click="handleCreate">
<IconCenter code="x6_add"></IconCenter>
<span>新建模型</span>
</div>
</div>
<div class="md-custom-node__child" v-else>
<div class="md-custom-node__name" :class="nodeData.modelType == 1 ? 'activity' : 'object'">
{{ nodeData.modelName }}
</div>
<div class="md-custom-node__code">{{ nodeData.modelCode }}</div>
</div>
</div>
</template>
事件触发与联动
节点内通过 X6 的事件系统向 Graph 触发自定义事件,外部由 EventManager 统一处理。
javascript
const handleCreate = () => {
const node = getNode()
const graph = node.model.graph
graph.trigger('custom', { node })
}
在事件管理器中使用 graph.on('custom', cb) 订阅,即可拿到节点上下文进行弹窗、路由或接口联动。
数据与子节点状态监听
更新节点数据
javascript
const handleDataChange = () => {
nodeData.value = node.getData()
}
更新子节点集合
javascript
const handleChildrenChange = () => {
nodeChildren.value = getNode().getChildren()
}
在 onMounted 中订阅节点变更事件,onUnmounted 中解除订阅以防止内存泄漏。
样式与动态绑定
使用 v-bind() 在 SASS 中绑定常量,保证主题一致性与灵活性。
- 父节点样式:customNode.vue:61-105
- 子节点样式(业务对象/活动):customNode.vue:106-137
scss
.md-custom-node__parent {
background: v-bind('NODE_COLORS.PARENT.CONCEPT');
}
.md-custom-node__name.object {
background: v-bind('NODE_COLORS.BUSTNESS_OBJECT.BACKGROUND');
}
与 NodeManager 的集成
NodeManager 负责注册形状与提供 Teleport 容器:
注册 Vue 节点
javascript
register({
shape: this.shapeName,
component: this.options.CustomNode,
ports: { /* 连接框配置 */ },
})
Teleport 容器
javascript
getTeleportContainer() {
// ...
}
在 Vue 画布组件中,将 Teleport 容器挂载出去:
javascript
TeleportContainer.value = managers.nodeManager.getTeleportContainer()
使用清单
- 在 ManagerFactory 选项中传入 CustomNode 组件
- 通过 nodeManager.getTeleportContainer() 挂载 Teleport
- 由 EventManager 订阅 graph.trigger('custom', ...) 事件,执行业务回调
通过组件化节点与事件联动,X6 的节点不仅是可视化元素,更是业务交互的入口。结合 NodeManager 与 EventManager,可形成清晰的职责边界与高内聚的交互设计。