<template>
<div style="height:100%;">
<Card :status="status" :pX="pX" :pY="pY" :list="menuRef" />
<div @click.right="rightMenu($event)">
右键点击</div>
</div>
</template>
//右键菜单开始
import Card from '@/components/Card/index.vue'
type MenuType = {
label: String
callback: () => void
}
const menuRef = ref<MenuType[]>()//右键列表
const status = ref<Boolean>(false)//右键菜单是否显示
const pX = ref<Number>(0)//右键对应的位置
const pY = ref<Number>(0)
const rightMenu = (event: any) => {
const bodyWidth = document.body.clientWidth
let mouseWidth = event.clientX
console.log(event)
if (bodyWidth - 200 < mouseWidth) { //处理边界问题,右键不会移到窗口外面
mouseWidth -= mouseWidth + 200 - bodyWidth
}
event.preventDefault()
pX.value = mouseWidth
pY.value = event.clientY
status.value = true
let menu = [
{
label: '新增',
callback: () => {
//回调函数 写自己想要的操作
},
},
{
label: '编辑',
callback: () => {
//回调函数 写自己想要的操作
},
},
{
label: '删除',
callback: () => {
ElMessageBox.confirm(
'确认删除吗?',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
center: true,
}
)
.then(() => {
ElMessage({
type: 'success',
message: 'Delete completed',
})
})
.catch(() => {
ElMessage({
type: 'info',
message: 'Delete canceled',
})
})
},
},
]
menuRef.value = menu
}
window.addEventListener('click', () => {
status.value = false
})
<template>
<nav
class="rightUl"
ref="menuRef"
:style="{ display: !status ? 'none' : '', left: pX + 'px', top: pY + 'px' }"
>
<li v-for="item in list" @click="item.callback()" class="rightLi">
{{ item.label }}
</li>
</nav>
</template>
<script lang="ts">
import { defineComponent, PropType, watch, ref } from 'vue'
type MenuType = {
label: String
callback: () => void
}
export default defineComponent({
name: 'Card',
props: {
pX: {
type: Number,
default: 0,
},
pY: {
type: Number,
default: 0,
},
status: {
type: Boolean,
default: false,
},
list: {
type: Array as PropType<MenuType[]>,
},
},
emits: [],
setup(props, { emit }) {
const menuRef = ref<HTMLElement>()
const body = document.querySelector('body')
watch(
() => props.status,
(val) => {
if (val && menuRef.value) {
body?.appendChild(menuRef.value)
} else if (menuRef.value) {
body?.removeChild(menuRef.value)
}
}
)
return {}
},
})
</script>
<style scoped lang="scss">
.rightUl{
position:fixed;
border-radius:5px;
width:100px;
color:#333;
background:#f2f2f2;
z-index:10;
}
.rightLi{
list-style-type: none;
height:30px;
line-height:30px;
width:100px;
text-align:center;
cursor:pointer;
}
.rightLi:first-child{
border-radius:5px 5px 0 0;
}
.rightLi:last-child{
border-radius:0 0 5px 5px;
}
.rightLi:hover {
background: #e1dddd;
}
</style>