Vue中 实现右键自定义菜单

1. 原生方法

1.1 完整代码

<template>
  <div class="home">
    <!-- 在需要右键菜单的元素,绑定contextmenu事件 -->
    <div 
    	class="test" v-for="item in menus" :key="item" 
    	@contextmenu.prevent="openMenu($event,item)">{{item}}</div>
    	
    <!-- 右键菜单部分 -->
    <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
      <li @click="handleDelete">删除</li>
      <li @click="handleDownloadFile">下载</li>
      <li @click="handlePreviewFile">预览</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      menus:[1,2,3], // 模拟数据
      rightClickItem:'',
      visible: false, // 是否展示右键菜单
      top:0,
      left:0,
    };
  },
  methods: {
    // 打开右键菜单
    openMenu(e,item){
      this.visible = true;
      this.top = e.pageY;
      this.left = e.pageX;
      this.rightClickItem = item;
    },
    // 关闭右键菜单
    closeMenu(){
      this.visible = false;
    },
	
    handleDelete(){},
    handleDownloadFile(){},
    handlePreviewFile(){},
  },
  watch: {
    // 监听 visible,来触发关闭右键菜单,调用关闭菜单的方法
    visible(value) {
      if (value) {
        document.body.addEventListener('click', this.closeMenu)
      } else {
        document.body.removeEventListener('click', this.closeMenu)
      }
    }
  },
};
</script>

<style lang="stylus" scoped>
.home{
  display: flex;
  justify-content: space-around;
  width: 100%;
  height: 600px;
  .test{
    width: 80px;
    height: 60px;
    background-color pink;
    text-align:center;
    font-size:32px;  
    color: green;
  }
  .contextmenu {
    margin: 0;
    background: #fff;
    z-index: 3000;
    position: absolute;
    list-style-type: none;
    padding: 5px 0;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 400;
    color: #333;
    box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
  }
  .contextmenu li {
    margin: 0;
    padding: 7px 16px;
    cursor: pointer;
  }
  .contextmenu li:hover {
    background: #eee;
  }
}
</style>

1.2 效果
在这里插入图片描述

2. 使用插件 vue-context-menu

demo演示地址
GitHub地址
npm 地址

安装

npm install vue-contextmenu --save

引入

import VueContextMenu from 'vue-contextmenu'
Vue.use(VueContextMenu)

2.1 普通列表菜单
2.1.1 完整代码

<template>
  <div 
    id="app" @contextmenu="showMenu"
    style="width: 200px;height: 200px;margin-top: 20px;background: pink;">
    <vue-context-menu 
      :contextMenuData="contextMenuData" @deleteData="deleteData" @newAdd="newAdd">
    </vue-context-menu>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 菜单数据
      contextMenuData: {
        menuName: 'demo',
        // 菜单显示的位置
        axis: {
          x: null,
          y: null
        },
        // 菜单选项
        menulists: [
          {
            fnHandler: 'deleteData', // 绑定事件
            icoName: 'el-icon-delete', // 图标 (本文取自 element-ui)
            btnName: '保存' // 菜单名称
          },{
            fnHandler: 'newAdd',
            icoName: 'el-icon-plus',
            btnName: '新增'
          }
        ]
      }
    };
  },
  methods: {
    showMenu () {
      event.preventDefault()
      var x = event.clientX;
      var y = event.clientY;
      // 获取当前位置
      this.contextMenuData.axis = { x, y }
    },
    // 删除
    deleteData () {},
    // 新增
    newAdd () {}
  },
  watch: {},
};
</script>

2.1.2 效果
在这里插入图片描述
2.2 树型菜单
2.2.1 完整代码

<template>
  <div style="position: fixed; left: 0px; top: 0">
    <div
      @contextmenu="showMenu(index)"
      style="width: 100px; height: 100px; margin-top: 20px; background: red"
      v-for="(n, index) in 2"
      :key="n"
    >
      <vue-context-menu
        :contextMenuData="contextMenuData"
        :transferIndex="transferIndex"
        @Handler1="Handler_A(index)"
        @Handler2="Handler_B(index)"
        @Handler3="Handler_C(index)"
      ></vue-context-menu>
    </div>
  </div>
</template>
<script>
export default {
  name: "app",
  data() {
    return {
      transferIndex: null,
      contextMenuData: {
        menuName: "demo",
        axis: {
          x: null,
          y: null,
        },
        menulists: [
          {
            btnName: "选项1",
            icoName: "el-icon-s-tools",
            children: [
              {
                icoName: "el-icon-download",
                btnName: "选项1-1",
                // 子菜单
                children: [
                  {
                    icoName: "el-icon-share",
                    btnName: "选项1-1-1",
                    children: [
                      {
                        icoName: "el-icon-switch-button",
                        fnHandler: "Handler1",
                        btnName: "选项1-1-1",
                      },
                    ],
                  },
                ],
              },
            ],
          },
          {
            btnName: "选项2",
            children: [
              {
                fnHandler: "Handler2",
                btnName: "选项2-1",
              },
            ],
          },
          {
            btnName: "选项3",
            fnHandler: "Handler3",
          },
          {
            btnName: "选项4",
            disabled: true,
          },
        ],
      },
    };
  },
  methods: {
    showMenu(index) {
      this.transferIndex = index; // 将索引转换到子组件
      event.preventDefault();
      var x = event.clientX;
      var y = event.clientY;
      this.contextMenuData.axis = { x,y };
    },
    Handler_A(index) {
      console.log(index, "选项 1-1-1 绑定事件执行");
    },
    Handler_B(index) {
      console.log(index, "选项 2-1 绑定事件执行");
    },
    Handler_C(index) {
      console.log(index, "选项 3 绑定事件执行");
    },
  },
};
</script>

<style>
* {
  margin: 0;
  padding: 0;
}
</style>

2.2.2 效果
在这里插入图片描述

参考文章

要在Vue实现自定义的鼠标右键菜单,你可以借助第三方插件或者自己编写代码来实现。下面是一个使用第三方插件 `vue-contextmenu` 的示例: 首先,安装 `vue-contextmenu` 插件: ```shell npm install vue-contextmenu ``` 然后,在你的Vue项目中,导入并注册 `vue-contextmenu` 插件: ```javascript import VueContextmenu from 'vue-contextmenu'; Vue.use(VueContextmenu); ``` 接下来,在需要添加右键菜单的元素上使用 `v-contextmenu` 指令,并绑定一个方法来定义菜单的内容和行为: ```html <template> <div> <div v-contextmenu="contextMenu"> Right-click me! </div> </div> </template> <script> export default { data() { return { contextMenu: [ { text: '菜单项1', action: 'menuItem1' }, { text: '菜单项2', action: 'menuItem2' }, { text: '菜单项3', action: 'menuItem3' } ] }; }, methods: { menuItem1() { console.log('执行菜单项1的操作'); }, menuItem2() { console.log('执行菜单项2的操作'); }, menuItem3() { console.log('执行菜单项3的操作'); } } }; </script> ``` 在这个例子中,`contextMenu` 数组定义了右键菜单的内容,每个菜单项都有一个 `text` 属性用于显示菜单项的文本,以及一个 `action` 属性用于定义菜单项被点击时要执行的方法。 运行项目后,当你在指定的元素上右键点击时,就会弹出自定义右键菜单,并执行相应的方法。 除了使用第三方插件外,你也可以根据需求自己编写代码来实现自定义的鼠标右键菜单。这需要使用原生JavaScript事件来捕获右键点击事件,并自定义菜单的样式和行为。 希望对你有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明天也要努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值