Vue自定义指令实现点击右键弹出菜单示例详解
xiaoxiaok 人气:0一、实现思路
1.使用contextmenu事件
该需求需要拦截浏览器的右击事件,更改为自定义监听事件,可使用@contextmenu.prevent直接绑定一个监听函数,它的作用就是拦截右击事件并触发绑定的监听事件。
其次,为了在右击的位置打开菜单,我们需要获取鼠标点击的位置;一般来说,若绑定的函数没有自定义参数,则可以直接使用默认的参数e来获取;若绑定的函数具有自定义参数,则需要定义$event来获取位置,即
@contextmenu.prevent="rightclick(index, indexMeasure, $event)
最后,通过参数event可获取鼠标点击的横向X轴值和竖直Y轴值,然后使用固定定位来对菜单进行偏移,因为固定定位是相对于浏览器窗口,且获取的X和Y轴值也是相对于浏览器窗口的。
#menu { z-index: 999; display: none; position: fixed; width: 150px; border: 1px solid #ccc; background: #eee; }
2.点击菜单之外的任意地方关闭菜单
在mounted里边监听全局的点击事件即可
mounted () { // 鼠标点击其他位置时隐藏菜单 document.onclick = function () { menu.style.display = 'none'; } }
3.菜单置于图层的最顶层
该需求是为了避免在点击菜单项时,触发了其他元素绑定的监听函数。这其实跟图层有关,我们只需要将菜单置到顶层即可。使用的是z-index属性,如下
#menu { z-index: 999; display: none; position: fixed; width: 150px; border: 1px solid #ccc; background: #eee; }
二、源代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用Vue自定义指令实现右键菜单</title> <script src="js/vue.js"></script> <style> /* 自定义右键菜单 */ #menu { z-index: 999; display: none; position: fixed; width: 150px; border: 1px solid #ccc; background: #eee; } #menu ul { margin: 5px 0; } #menu li { height: 30px; line-height: 30px; color: #21232E; font-size: 12px; text-align: center; cursor: default; list-style-type: none; border-bottom: 1px dashed #cecece; } #menu li:hover { background-color: #cccccc; } .block { height: 300px; width: 400px; background-color: pink; margin-bottom: 15px; } </style> </head> <body> <div id="itany"> <div style="position: relative;"> <div class="block" v-rightclick>1</div> <div class="block" v-rightclick>2</div> <div class="block" v-rightclick>3</div> <div class="block" v-rightclick>4</div> <div class="block" v-rightclick>5</div> <div class="block" v-rightclick>6</div> <!-- 自定义鼠标右键菜单 --> <div id="menu"> <ul> <li v-for="item in rightMenuList" @click="item.handler"> {{item.text}} </li> </ul> </div> </div> </div> <script> Vue.directive('rightclick', function (el, binding) { el.oncontextmenu = function (e) { console.log('e.clientY', e.clientY) // console.log('e.clientX', e.clientX) e.preventDefault(); menu.style.display = 'block'; menu.style.left = e.clientX + 'px'; menu.style.top = e.clientY + 'px'; } }); var vm = new Vue({ el: '#itany', data: { rightMenuList: [ { id: 0, text: "开通道", handler: () => { alert('通道开启成功'); } }, { id: 1, text: "关通道", handler: () => { alert('通道关闭成功'); } }, { id: 2, text: "重启通道", handler: () => { alert('通道重启成功'); } }, ] }, methods: { }, mounted () { // 鼠标点击其他位置时隐藏菜单 document.onclick = function () { menu.style.display = 'none'; } } }); </script> </body> </html>
加载全部内容