vue3+jointjs 使用模板添加元素

发布时间 2023-04-25 09:46:34作者: longlinji
关于如何在 Vue3 和 JointJS 中使用拖拽模板来创建节点元素,可以按照以下步骤进行:

1. 安装 JointJS

使用 npm 进行安装:

```
npm install jointjs
```

2. 在 Vue3 中创建 JointJS 容器

在 Vue3 中创建一个组件,用于创建 JointJS 的画布和节点。在组件的生命周期方法 `mounted` 中,创建 JointJS 的 `Paper` 和 `Graph` 对象:

```vue
<template>
  <div class="jointjs-container"></div>
</template>

<script>
import { Paper, Graph } from 'jointjs'

export default {
  mounted() {
    const paper = new Paper({
      el: '.jointjs-container',
      width: 800,
      height: 600,
      model: new Graph(),
      gridSize: 10,
      drawGrid: true,
      background: {
        color: '#f9f9f9'
      }
    })
  }
}
</script>

<style scoped>
.jointjs-container {
  border: 1px solid #ccc;
}
</style>
```

3. 创建节点模板

在 JointJS 中,可以使用 `joint.shapes` 来创建节点模板。创建一个名为 `my-custom-shape` 的节点模板:

```javascript
const myCustomShape = new joint.shapes.standard.Circle({
  position: { x: 100, y: 100 },
  size: { width: 50, height: 50 },
  attrs: {
    body: {
      fill: 'lightblue'
    },
    label: {
      text: 'My Custom Shape'
    }
  }
})
```

这个模板是一个圆形节点,填充色为浅蓝色,显示一个标签文本。

4. 定义拖拽逻辑

在组件中定义拖拽逻辑,可以使用 `jquery-ui` 的拖拽和放置插件。首先,需要在组件的 `mounted` 方法中引入 `jquery-ui`:

```vue
<script>
import { Paper, Graph } from 'jointjs'
import $ from 'jquery'
import 'jquery-ui/ui/widgets/draggable'
import 'jquery-ui/ui/widgets/droppable'

export default {
  mounted() {
    const paper = new Paper({
      // ...
    })

    $(paper.el).droppable({
      tolerance: 'fit',
      drop: (event, ui) => {
        const x = ui.offset.left
        const y = ui.offset.top
        // 在这里创建新的节点元素
      }
    })

    $('#my-custom-shape').draggable({
      cursor: 'move',
      helper: 'clone',
      stop: (event, ui) => {
        // 在这里拖动结束时删除复制的节点
        ui.helper.remove()
      }
    })
  }
}
</script>
```

在 `drop` 回调函数中,获取鼠标落下位置的坐标,接下来可以在这里创建新的节点元素。

在 `draggable` 方法中,定义允许拖拽和放置的节点模板。在这里使用 `helper: 'clone'`,允许复制原节点,而不是移动节点。

5. 创建新节点

在 `drop` 回调函数中,通过 `paper.model.addCell()` 方法创建新节点,然后将节点添加到画布中:

```vue
<script>
export default {
  mounted() {
    const paper = new Paper({
      // ...
    })

    $(paper.el).droppable({
      // ...
      drop: (event, ui) => {
        const x = ui.offset.left
        const y = ui.offset.top
        const cell = myCustomShape.clone()
        cell.position(x, y)
        paper.model.addCell(cell)
      }
    })

    $('#my-custom-shape').draggable({
      // ...
    })
  }
}
</script>
```

使用 `myCustomShape.clone()` 复制节点模板,然后使用 `cell.position(x, y)` 设置新节点的位置坐标。最后,使用 `paper.model.addCell(cell)` 添加新节点到画布中。

完整代码如下:

```vue
<template>
  <div class="jointjs-container"></div>
</template>

<script>
import { Paper, Graph } from 'jointjs'
import $ from 'jquery'
import 'jquery-ui/ui/widgets/draggable'
import 'jquery-ui/ui/widgets/droppable'

const myCustomShape = new joint.shapes.standard.Circle({
  position: { x: 100, y: 100 },
  size: { width: 50, height: 50 },
  attrs: {
    body: {
      fill: 'lightblue'
    },
    label: {
      text: 'My Custom Shape'
    }
  }
})

export default {
  mounted() {
    const paper = new Paper({
      el: '.jointjs-container',
      width: 800,
      height: 600,
      model: new Graph(),
      gridSize: 10,
      drawGrid: true,
      background: {
        color: '#f9f9f9'
      }
    })

    $(paper.el).droppable({
      tolerance: 'fit',
      drop: (event, ui) => {
        const x = ui.offset.left
        const y = ui.offset.top
        const cell = myCustomShape.clone()
        cell.position(x, y)
        paper.model.addCell(cell)
      }
    })

    $('#my-custom-shape').draggable({
      cursor: 'move',
      helper: 'clone',
      stop: (event, ui) => {
        ui.helper.remove()
      }
    })
  }
}
</script>

<style scoped>
.jointjs-container {
  border: 1px solid #ccc;
}
</style>
```