vue3 div 点击右键旁边出现弹窗 可做编辑删除 新增操作
完整代码:
<template>
<div
v-for="(item, index) in list"
:key="index"
class="list-item"
@contextmenu.prevent="(e) => showMenu(e, item)"
>
{{ item.name }}
</div>
<!-- 弹窗组件 -->
<Teleport to="body">
<div
v-if="showContextMenu"
class="context-menu"
:style="menuStyle"
>
<div class="menu-item" @click="handleAction('edit', currentItem)">
编辑 {{ currentItem?.name }}
</div>
<div class="menu-item" @click="handleAction('delete', currentItem)">
删除
</div>
</div>
</Teleport>
</template>
<script setup>
import {ref} from 'vue'
const list = ref([
{id: 1, name: 1},
{id: 2, name: 2},
{id: 3, name: 3},
{id: 4, name: 4},
{id: 5, name: 5},
{id: 6, name: 6},
{id: 7, name: 7},
{id: 8, name: 8},
])
const showContextMenu = ref(false)
const menuStyle = ref({left: '0px', top: '0px'})
const currentItem = ref(null)
// 右键菜单显示逻辑
const showMenu = (event, item) => {
currentItem.value = item
showContextMenu.value = true
// 位置计算(带视口边界检测)
const {clientX, clientY} = event
const viewportWidth = window.innerWidth
const viewportHeight = window.innerHeight
menuStyle.value = {
left: `${Math.min(clientX, viewportWidth - 200)}px`,
top: `${Math.min(clientY, viewportHeight - 150)}px`
}
}
// 菜单操作处理
const handleAction = (type, item) => {
console.log('操作类型:', type, '当前数据:', item)
showContextMenu.value = false
}
// 点击外部关闭(通过事件委托优化)
document.addEventListener('click', () => {
showContextMenu.value = false
})
</script>
<style>
.list-item {
padding: 12px;
border: 1px solid #eee;
margin: 8px;
cursor: context-menu;
}
.context-menu {
position: fixed;
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
border-radius: 4px;
z-index: 9999;
}
.menu-item {
padding: 8px 16px;
transition: background 0.2s;
}
.menu-item:hover {
background: #f5f5f5;
}
</style>
效果: