89 lines
1.6 KiB
Vue
89 lines
1.6 KiB
Vue
|
|
<template>
|
|||
|
|
<div
|
|||
|
|
v-if="visible"
|
|||
|
|
class="context-menu"
|
|||
|
|
:style="{ top: position.y + 'px', left: position.x + 'px' }"
|
|||
|
|
>
|
|||
|
|
<div
|
|||
|
|
v-for="item in menuItems"
|
|||
|
|
:key="item.key"
|
|||
|
|
class="menu-item"
|
|||
|
|
@click="handleClick(item)"
|
|||
|
|
>
|
|||
|
|
{{ item.label }}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import { ref, watch, onMounted, onUnmounted } from 'vue';
|
|||
|
|
|
|||
|
|
const props = defineProps({
|
|||
|
|
visible: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: false
|
|||
|
|
},
|
|||
|
|
position: {
|
|||
|
|
type: Object,
|
|||
|
|
default: () => ({ x: 0, y: 0 })
|
|||
|
|
},
|
|||
|
|
menuItems: {
|
|||
|
|
type: Array,
|
|||
|
|
default: () => []
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const emit = defineEmits(['close', 'select']);
|
|||
|
|
|
|||
|
|
watch(() => props.visible, (newVal) => {
|
|||
|
|
if (newVal) {
|
|||
|
|
document.addEventListener('click', closeMenu);
|
|||
|
|
} else {
|
|||
|
|
document.removeEventListener('click', closeMenu);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const handleClick = (item) => {
|
|||
|
|
emit('select', item);
|
|||
|
|
closeMenu();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const closeMenu = () => {
|
|||
|
|
emit('close');
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
onMounted(() => {
|
|||
|
|
// 初始监听(如果visible初始为true)
|
|||
|
|
if (props.visible) {
|
|||
|
|
document.addEventListener('click', closeMenu);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
onUnmounted(() => {
|
|||
|
|
document.removeEventListener('click', closeMenu);
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped>
|
|||
|
|
.context-menu {
|
|||
|
|
position: fixed; /* 使用 fixed 定位,不受父容器 scroll 影响 */
|
|||
|
|
z-index: 9999;
|
|||
|
|
background-color: #fff;
|
|||
|
|
border: 1px solid #eee;
|
|||
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|||
|
|
border-radius: 4px;
|
|||
|
|
padding: 5px 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.menu-item {
|
|||
|
|
padding: 8px 15px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
font-size: 14px;
|
|||
|
|
color: #606266;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.menu-item:hover {
|
|||
|
|
background-color: #f5f7fa;
|
|||
|
|
}
|
|||
|
|
</style>
|