vue3实现右击鼠标出现菜单

vue-contextmenu库:vue3使用的时候报错,runtime helper错误,不知道咋解决

vue3-menus库:vue3-menus - npm (npmjs.com)

有三种使用方式

1、自定义指令

2、方法

3、组件(项目最后使用的是这个,因为要实现鼠标左击菜单消失)

vue文件

 <div class="left-container" @click.stop @contextmenu="rightClick($event, MenuType.Blank, {})" @click="isOpen = false">

    <!-- 右击菜单组件 -->
    <vue3-menus v-model:open="isOpen" :event="eventVal" :menus="currentMenus">
      <template #label="{ menu }">{{ menu.label }}</template>
    </vue3-menus>

<script setup lang="ts">
import { Vue3Menus } from 'vue3-menus' //引入
//右击菜单自定义hook
import rightMenu from './components/rightMenu'
//右击菜单枚举类
enum MenuType {
  Blank = 'blank',
  Group = 'group',
  Instance = 'instance'
}
let {
  isOpen,
  eventVal,
  currentMenus,
  rightClick,
  handleCreateGroup,
  visibleGroupDialog,
  groupDialogData,
  closeDialog
} = rightMenu()
</script>

自定义hook文件:rightMenu.ts

import { shallowRef, nextTick, ref, computed, reactive } from 'vue'
//菜单类型
type MenuItem = {
  label: string
  click: () => void
}
//菜单枚举类
enum MenuType {
  Blank = 'blank',
  Group = 'group',
  Instance = 'instance'
}
//与右击出现菜单相关的自定义hook
export default function rightMenu() {
  const visibleGroupDialog = ref<boolean>(false) //是否打开分组操作弹框
  // 关闭分组操作弹框
  function closeDialog(): void {
  }
  // 定义传递给弹框的数据类型
  interface groupDataType {
    visible: boolean
    type: string
    groupId: string
    groupName: string
  }
  //传递给弹框组件的数据
  const groupDialogData = reactive<groupDataType>({
    visible: false,
    type: '',
    groupId: '',
    groupName: ''
  })
  /**
   * 创建分组
   */
  function handleCreateGroup(): void {

  }
  /**
   * 编辑分组
   */
  function handleEditGroup(groupId: string, groupName: string) {
  }
  /**
   * 删除分组
   */
  function handleDeleteGroup(groupId: string, groupName: string) {

  }
  const isOpen = ref<boolean>(false)
  //菜单的数据类型

  //点击空白处出现的菜单
  const blankMenus = shallowRef<MenuItem[]>([
    {
      label: '刷新列表',
      click: () => {}
    },
    {
      label: '新建分组',
      click: () => handleCreateGroup()
    }
  ])
  //点击空白处出现的菜单
  const groupMenus = shallowRef([
    {
      label: '刷新列表',
      click: () => {}
    },
    {
      label: '新建分组',
      click: () => handleCreateGroup()
    },
    {
      label: '删除分组',
      click: () => handleDeleteGroup(groupId.value, groupName.value)
    },
    {
      label: '编辑分组名称',
      click: () => handleEditGroup(groupId.value, groupName.value)
    },
    {
      label: '上移',
      click: () => {}
    },
    {
      label: '下移',
      click: () => {}
    }
  ])
  //点击实例处出现的菜单
  const instanceMenus = shallowRef<MenuItem[]>([
    {
      label: '刷新列表',
      click: () => {}
    },
    {
      label: '新建分组',
      click: () => handleCreateGroup()
    },
    {
      label: '移动分组',
      click: () => {}
    }
  ])

  const eventVal = ref<MouseEvent | null>(null) //事件对象
  const groupId = ref<string>('') //分组id
  const groupName = ref<string>('') //分组名称
  /**
   * 右击鼠标的回调
   * @param event 事件
   * @param type  类型,有blank,group和instance
   */
  function rightClick(event: MouseEvent, type: MenuType, item) {
    menuType.value = type
    isOpen.value = false
    nextTick(() => {
      eventVal.value = event
      isOpen.value = true
    })
    event.preventDefault()
    event.stopPropagation()
    //如果传来item,获取分组id和分组名
    if (item) {
      groupId.value = item.phoneId
      groupName.value = item.name
    }
  }

  const menuType = ref<MenuType>(MenuType.Blank) // 默认空白菜单
  // 计算当菜单
  const currentMenus = computed((): MenuItem[] => {
    switch (menuType.value) {
      case 'group':
        return groupMenus.value
      case 'instance':
        return instanceMenus.value
      default:
        return blankMenus.value
    }
  })
  return {
    isOpen,
    eventVal,
    rightClick,
    currentMenus,
    handleCreateGroup,
    visibleGroupDialog,
    groupDialogData,
    closeDialog
  }
}

注意:三个事件的顺序


如果希望鼠标右击mousedown事件: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值