Vue Teleport 实现右键菜单需动态创建唯一容器并复用,结合事件坐标(pageX/Y)与内联样式定位,使用 position: fixed 避免父级影响,并通过全局 click 监听实现点击外部隐藏。
Vue 的 Teleport 本身不直接处理坐标定位,它只负责把内容“挪”到目标 DOM 节点里。要在右键菜单中实现根据点击坐标精准显示,关键在于:传送内容 + 动态定位样式,两者配合完成。
右键菜单不能依赖固定 ID(比如 #context-menu)在 HTML 中提前写死,否则多个菜单实例会冲突或覆盖。推荐做法是:
mounted 或首次右键时,动态创建一个唯一容器(如 div[data-context="menu-uuid"]),并 append 到 document.body
teleport :to 的目标Teleport 把菜单内容传过去后,菜单自身需根据事件坐标决定位置。常见方式:
contextmenu 事件,捕获 event.clientX 和 event.clientY
:style="{ left: x + 'px', top: y + 'px' }" 定位left: Math.min(x, window.innerWidth - width))单纯用 clientX/Y 在页面滚动或缩放时容易偏移。更健壮的做法:
getBoundingClientRect() 获取视口相对坐标,再结合 window.scrollX/Y 计算绝对位置event.pageX/event.pageY(兼容性好,已含滚动偏移)position: fixed,这样定位不受父级 transform 或 overflow 影响右键菜单常需自动关闭或点击外部隐藏。注意:
click 全局事件,点击非菜单区域就隐藏