前言
鼠标右键菜单想必大家都不陌生,在我们日常开发中可能需要自定义一下右键菜单,让右键菜单列表变成我们想要的列表,本节我们就来自定义一个右键菜单组件。
contextmenu
contextmenu事件是我们右键点击鼠标时触发的事件。当用户单击鼠标右键时,浏览器就会触发contextmenu事件,然后显示出菜单列表。该事件跟click、keyup等事件一样是在HTML元素上注册的,如果我们在vue中使用的话也是通过@来调用。
<template>
<div @contextmenu="showMenu">Right-click</div>
</template>
<script>
export default {
methods: {
showMenu(event) {
console.log('点击了右键');
}
}
};
</script>
菜单组件
自定义的菜单组件肯定需要通过contextmenu时间来触发,但是现在右键出现的是默认菜单列表,怎么让默认菜单不再出现?通过preventDefault来阻止默认事件即可。我们在组件中监听contextmenu并且阻止它的默认事件,然后换上我们自定义的事件。
window.addEventListener('contextmenu', e => {
e.preventDefault();
//触发自定义事件
this.showMenu();
});
这样核心代码我们就得到了,我们自定义菜单主要是为了改变菜单的样式和功能,样式一般可以固定,而具体功能可能有所不同,所以我们可以定义options参数来接受菜单展现的数据。至此我们静态页面就能得到,菜单样式我们可以根据需要自定义。
template>
<div>
<ul :id="elementId" v-click-outside="onClickOutside" class="vue-simple-context-menu">
<li
v-for="(option, index) in options"
:key="index"
class="vue-simple-context-menu__item"
@click="optionClicked(option)"
>{{ option.name }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'VueContextMenu',
props: {
//菜单id
elementId: {
type: String,
required: true
},
//菜单项
options: {
type: Array,
required: true
}
},
data() {
return {
item: null,
menuWidth: null,
menuHeight: null
}
}
}
</script>
<style lang="scss">
</style>
接下来补充对应的功能即可,我们需要根据不同选项去执行不同的效果,利用$emit传递参数在父组件执行对应的时间。我们也可以直接写死对应的事件,然后就是showMenu事件,我们需要获取当前坐标位置,将菜单定位点击位置附近。
methods: {
//计算菜单位置
showMenu(item) {
const event = window.event || event
this.item = item
const menu = document.getElementById(this.elementId)
if (!menu) {
return
}
if (!this.menuHeight) {
menu.style.visibility = 'hidden'
menu.style.display = 'block'
// this.menuWidth = menu.offsetWidth
this.menuHeight = menu.offsetHeight
menu.removeAttribute('style')
}
if (this.menuWidth + event.pageX) {
menu.style.left = event.pageX - this.menuWidth + 2 + 'px'
} else {
menu.style.left = event.pageX - 2 + 'px'
}
if (this.menuHeight + event.pageY >= window.innerHeight) {
menu.style.top = event.pageY - this.menuHeight + 2 + 'px'
} else {
menu.style.top = event.pageY - 2 + 'px'
}
menu.classList.add('vue-simple-context-menu--active')
},
//点击菜单外区域隐藏菜单
onClickOutside() {
this.hideContextMenu()
},
hideContextMenu() {
const element = document.getElementById(this.elementId)
if (element) {
element.classList.remove('vue-simple-context-menu--active')
}
},
//菜单项触发事件并且隐藏菜单
optionClicked(option) {
this.$emit('option-clicked', { item: this.item, option: option })
this.hideContextMenu()
}
}
总结
以上就是自定义右键菜单,主要运用contextmenu事件,我们可以根据自己需要去做相关优化。