vue3使用@antv/x6-边工具的右键菜单实现

官方文档是react实现的,但项目里使用的vue3+elementPlus,经过研究后通过以下方式实现:

  1. 在根目录的index.html里添加右键菜单的元素
<body>
<!-- 模型的自定义工具容器 -->
+ <div id="graph-dropdown"></div>
<div id="app">
  <div id="loader-wrapper">
    <div id="loader"></div>
    <div class="loader-section section-left"></div>
    <div class="loader-section section-right"></div>
    <div class="load_title">正在加载系统资源,请耐心等待</div>
  </div>
</div>

还有该元素的css属性

#graph-dropdown {
  position: absolute;
  z-index: 2;
  background-color: #fff;
  top: 0;
  left: 0;
}
  1. 定义工具类
    contextMenuTool.jsx
import { ElDropdown, ElButton } from 'element-plus'
import { ToolsView } from '@antv/x6'
import { createApp } from 'vue'

// ContextMenu挂载的Vue实例
let app = null;
let timer = null; // timer

class ContextMenuTool extends ToolsView.ToolItem {
  toggleContextMenu(visible, pos) {
    if (app) {
      // 清空上次内容
      app.unmount();
      document.getElementById('graph-dropdown').innerHTML = '';
      app = null
    }
    document.removeEventListener('mousedown', this.onMouseDown)

    if (visible && pos) {
      app = createApp(
        <ElDropdown
          trigger={['contextmenu']}
        >
          {{
            default: () => {
              // menu是在createEdge传入的args
              if (Array.isArray(this.options.menu)) {
                return <div style="padding: 10px;">
                  {
                    this.options.menu.map(item => {
                      return <ElButton style="margin-left: 0;display:block;border: 0;" icon={item.icon} onClick={item.onClick}>{ item.label }</ElButton>
                    })
                  }
                </div>
              }
            }
          }}
        </ElDropdown>)
      // 减去本身元素的宽高
      document.getElementById('graph-dropdown').style = `left: ${pos.x - 40}px;top: ${pos.y - 40}px;`
      app.mount('#graph-dropdown')
      document.addEventListener('mousedown', this.onMouseDown)
    }
  }


  onMouseDown = () => {
    timer = window.setTimeout(() => {
      this.toggleContextMenu(false)
    },200)
  }

  onContextMenu({ e }) {
    debugger
    if (timer) {
      clearTimeout(timer)
      timer = 0
    }
    this.toggleContextMenu(true, { x: e.pageX, y: e.pageY })
  }

  delegateEvents() {
    this.cellView.on('cell:contextmenu', this.onContextMenu, this)
    return super.delegateEvents()
  }

  onRemove() {
    this.cellView.off('cell:contextmenu', this.onContextMenu, this)
  }
}

ContextMenuTool.config({
  tagName: 'div',
  isSVGElement: false
})

export {
  ContextMenuTool
}

  1. vue中使用
// 画布中自定义右键菜单工具的类
import { ContextMenuTool } from "../components/contextMenuTool"

// 在初始化画布之前注册自定义工具
Graph.registerEdgeTool('contextmenu', ContextMenuTool, true)

graph = new Graph({
    container: document.getElementById('container'),
    ...GRAPH_CONFIG,
    connecting: { // 连线规则
      ...CONNECTING_CONFIG,
      createEdge() {
        return new Shape.Edge({
          tools: [
            {
              name: 'contextmenu',
              args: {
                menu: [
                  { label: '删除连接线', onClick: () => console.log('删除'), icon: Delete },
                  { label: '对应关系', onClick: () => console.log('查看'), icon: Connection }
                ]
              }
            }
          ]
        })
      }
    }
  });

若是使用的其他ui框架,变更下拉菜单组件即可。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值