# antv-x6-vue2-shape

> x6 shape for rendering vue 2 components with teleport polyfill

this package is based on [@antv/x6-vue-shape](https://www.npmjs.com/package/@antv/x6-vue-shape) (keep updated with @antv/x6-vue-shape at v2.1.2)

but with the following key improvements for Vue2-only scenarios:

- Removed vue-demi dependency: Fully optimized for Vue2, eliminating cross-version compatibility code to reduce package size and improve runtime efficiency.
- Added Teleport polyfill support: For the first time, brings Vue3's native teleport capability to Vue2 environments, solving the rendering context isolation issue when embedding Vue components in X6 nodes.
- Optional Teleport mode: The Teleport feature is optional. If you don't call useTeleport(), it behaves exactly like the original @antv/x6-vue-shape (Vue2 version). When enabled via useTeleport({ target: HTMLElement | string }), you can specify a custom DOM container for component mounting.

`antv-x6-vue2-shape`是专门针对 Vue2 的场景，去除了 vue-demi 本版兼容工具，提供了 Teleport polyfill 的支持，以解决 Vue2 下 X6 动态节点导致的渲染上下文丢失、事件冒泡异常等问题。

- 未启用 Teleport：组件直接渲染在 X6 节点的默认容器中，与原始 @antv/x6-vue-shape (Vue2) 完全一致。
- 启用 Teleport：组件将通过 Polyfill 渲染到指定的 target 容器中，缓解 Vue2 下因 X6 动态节点导致的 DOM 上下文丢失和事件冒泡异常问题，使渲染行为在 DOM 层面更接近 Vue3 的原生 Teleport（但不完全支持跨层级的 provide/inject 等上下文传递）。

## Installation

```shell
# npm
$ npm install @antv/x6 antv-x6-vue2-shape --save

# yarn
$ yarn add @antv/x6 antv-x6-vue2-shape

# pnpm
pnpm add @antv/x6 antv-x6-vue2-shape
```

## Usage

```vue
<template>
  <div>
    <h1>Vue2 + X6 + antv-x6-vue2-shape 自定义节点示例</h1>
    <div
      id="container"
      style="
        width: 100%;
        height: 600px;
        border: 2px solid #e0e0e0;
        margin-top: 20px;
      "
    ></div>
    <div id="teleport-target"></div>
  </div>
</template>

<script>
import { Graph } from '@antv/x6'
import { useTeleport, register } '@antv-x6-vue2-shape'

const HelloWorld = {
  data() {
    return {
      name: 'x6-vue2-shape',
    }
  },
  render(h) {
    return h('div', [`Hello ${this.name}`])
  }
}

export default {
  mounted() {
    this.init()
  },
  methods: {
    init() {
      // 启用 Teleport 功能，指定 Teleport 挂载点（可选）
      useTeleport({
        target: '#teleport-target' // 支持 CSS 选择器或 HTMLElement
      })

      const graph = new Graph({
        container: document.getElementById("container"),
        grid: { size: 10, visible: true }, // 显示更细的网格
        background: { color: "#f8f9fa" }, // 设置背景色
      });

      // 注册自定义节点
      register({
        name: 'vue-shape',
        component: HelloWorld,
      })

      // 添加节点
      graph.addNode({shape: 'vue-shape', x: 32, y: 48, width: 180, height: 40})
    }
  }
}
</script>
```
