Vue3 + AntV/X6 自定义节点实践:组件化节点与事件联动

在图建模应用中,节点除了展示信息,还需要具备交互能力(创建、编辑、联动等)。借助 @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,可形成清晰的职责边界与高内聚的交互设计。

相关推荐
mocoding1 分钟前
使用鸿蒙化Flutter图片选择、相机拍照、多图选择三方库image_picker实战教程示例
flutter·前端框架·harmonyos·鸿蒙
IT教程资源D5 小时前
[N_160]基于springboot,vue校园论坛系统
mysql·vue·前后端分离·springboot校园论坛·校园论坛交流系统
liu_bees6 小时前
微信小程序Canvas生成图片失败:canvas is empty问题解析
微信小程序·小程序·uni-app·vue
super_lzb7 小时前
VUE 请求代理地址localhost报错[HPM] Error occurred while trying to proxy request
java·spring·vue·springboot·vue报错
Jinuss8 小时前
源码分析之React中Scheduler调度器的任务优先级
前端·react.js·前端框架
Aotman_9 小时前
Vue el-table 表尾合计行
前端·javascript·vue.js·elementui·前端框架·ecmascript
phltxy9 小时前
Vue3 + Vite:从入门到实战——核心指令全解析
vue.js·vue
经年未远21 小时前
vue3中实现耳机和扬声器切换方案
javascript·学习·vue
晚霞的不甘1 天前
Flutter for OpenHarmony 实现高级视差侧滑菜单:融合动效、模糊与交互动画的现代 UI 设计
flutter·ui·前端框架·交互·鸿蒙
RichardLau_Cx1 天前
【保姆级实操】MediaPipe SDK/API 前端项目接入指南(Web版,可直接复制代码)
前端·vue·react·webassembly·mediapipe·手部追踪·前端计算机视觉