vue3 鼠标右键菜单


html
<template>
  <div>
    <table class="min-w-full divide-y divide-gray-200">
      <thead class="bg-gray-50">
        <tr>
          <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
          <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Email</th>
          <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Role</th>
        </tr>
      </thead>
      <tbody class="bg-white divide-y divide-gray-200">
        <tr v-for="(user, index) in users" :key="user.id" @contextmenu.prevent="showContextMenu($event, user)">
          <td class="px-6 py-4 whitespace-nowrap">{{ user.name }}</td>
          <td class="px-6 py-4 whitespace-nowrap">{{ user.email }}</td>
          <td class="px-6 py-4 whitespace-nowrap">{{ user.role }}</td>
        </tr>
      </tbody>
    </table>
    <ContextMenu v-if="contextMenuVisible" :x="contextMenuX" :y="contextMenuY" :user="selectedUser" @close="contextMenuVisible = false" />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import ContextMenu from './ContextMenu.vue';

const users = ref([
  { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
  // 更多用户数据...
]);

const contextMenuVisible = ref(false);
const contextMenuX = ref(0);
const contextMenuY = ref(0);
const selectedUser = ref(null);

function showContextMenu(event, user) {
  contextMenuX.value = event.clientX;
  contextMenuY.value = event.clientY;
  selectedUser.value = user;
  contextMenuVisible.value = true;
}
</script>

右键菜单组件ContextMenu.vue:

html
<template>
  <div :style="{ top: `${y}px`, left: `${x}px` }" class="absolute bg-white shadow-lg rounded-md p-2 z-50">
    <p class="text-sm text-gray-700">操作: {{ user.name }}</p>
    <button @click="handleAction('edit')" class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">编辑</button>
    <button @click="handleAction('delete')" class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">删除</button>
    <button @click="closeMenu" class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">取消</button>
  </div>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue';

const props = defineProps({
  x: Number,
  y: Number,
  user: Object
});

const emit = defineEmits(['close']);

function handleAction(action) {
  console.log(`执行操作: ${action} 对象:`, props.user);
  closeMenu();
}

function closeMenu() {
  emit('close');
}
</script>