ContextMenu.vue 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. <script setup lang="ts">
  2. import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus'
  3. import { PropType, ref } from 'vue'
  4. import { useI18n } from '@/hooks/web/useI18n'
  5. import { useDesign } from '@/hooks/web/useDesign'
  6. import type { RouteLocationNormalizedLoaded } from 'vue-router'
  7. import { contextMenuSchema } from '../../../types/contextMenu'
  8. const { getPrefixCls } = useDesign()
  9. const prefixCls = getPrefixCls('context-menu')
  10. const { t } = useI18n()
  11. const emit = defineEmits(['visibleChange'])
  12. const props = defineProps({
  13. schema: {
  14. type: Array as PropType<contextMenuSchema[]>,
  15. default: () => []
  16. },
  17. trigger: {
  18. type: String as PropType<'click' | 'hover' | 'focus' | 'contextmenu'>,
  19. default: 'contextmenu'
  20. },
  21. tagItem: {
  22. type: Object as PropType<RouteLocationNormalizedLoaded>,
  23. default: () => ({})
  24. }
  25. })
  26. const command = (item: contextMenuSchema) => {
  27. item.command && item.command(item)
  28. }
  29. const visibleChange = (visible: boolean) => {
  30. emit('visibleChange', visible, props.tagItem)
  31. }
  32. const elDropdownMenuRef = ref<ComponentRef<typeof ElDropdown>>()
  33. defineExpose({
  34. elDropdownMenuRef,
  35. tagItem: props.tagItem
  36. })
  37. </script>
  38. <template>
  39. <ElDropdown
  40. ref="elDropdownMenuRef"
  41. :class="prefixCls"
  42. :trigger="trigger"
  43. placement="bottom-start"
  44. @command="command"
  45. @visible-change="visibleChange"
  46. popper-class="v-context-menu-popper"
  47. >
  48. <slot></slot>
  49. <template #dropdown>
  50. <ElDropdownMenu>
  51. <ElDropdownItem
  52. v-for="(item, index) in schema"
  53. :key="`dropdown${index}`"
  54. :divided="item.divided"
  55. :disabled="item.disabled"
  56. :command="item"
  57. >
  58. <Icon :icon="item.icon" /> {{ t(item.label) }}
  59. </ElDropdownItem>
  60. </ElDropdownMenu>
  61. </template>
  62. </ElDropdown>
  63. </template>