父级页面
<!--
* @LastEditTime: 2024-08-05 22:30:42
-->
<template>
<div class="content">
<span
class="content-menu"
:style="{
background:item.check?'yellow':'',
color:item.check?'black':'',
}"
:id="index"
v-for="(item,index) in listone"
:key="item.label"
>{{item.label}}</span>
<ContextMenu
v-if="showMenu"
class="block"
:x="x"
:y="y"
:menu="list"
@select="choose3 = $event.label"
></ContextMenu>
</div>
</template>
<script>
import $ from "jquery"
import ContextMenu from './components/ContextMenu.vue'
export default {
components: {
ContextMenu: ContextMenu,
},
data() {
return {
listone: [
{
label: '数据一',
check: false,
},
{
label: '数据二',
check: false,
},
{
label: '数据三',
check: false,
}
],
list: [
{
label: '选择'
},
{
label: '删除'
},
{
label: '移动'
}
],
showMenu: false,
shiftKey: false,
x: '',
y: '',
}
},
mounted() {
document.addEventListener('keydown', (event) => {
if (event.key === 'Shift') {
console.log('Shift 键被按下了!');
this.shiftKey = true
}
});
document.addEventListener('keyup', (event) => {
if (event.key === 'Shift') {
this.shiftKey = false
console.log('Shift 键被松开了!');
// 执行其他逻辑
}
});
// keyboardJS.bind('shift', (e) => {
// this.shiftKey = true
// console.log('Shift 键被按下了!');
// }, (e) => {
// this.shiftKey = false
// console.log('Shift 键被松开了!');
// });
// 添加右击事件监听器到整个文档
document.addEventListener('contextmenu', (event) => {
event.preventDefault();
event.stopPropagation(); // 阻止冒泡
var targetElement = event.target;
var classNames = targetElement.className;
if (classNames == "content-menu") {
this.x = event.clientX;
this.y = event.clientY;
this.showMenu = true;
} else {
if (this.showMenu) {
this.showMenu = false;
}
}
});
// 添加点击事件监听器到整个文档,用于隐藏菜单
document.addEventListener('click', (event) => {
event.preventDefault();
event.stopPropagation(); // 阻止冒泡
var targetElement = event.target;
var classNames = targetElement.className;
if (this.showMenu) {
this.showMenu = false;
}
if (classNames == "content-menu") {
if (!this.shiftKey) { //判断shift状态
this.listone.forEach(v => {
if (v.check) {
v.check = false
}
})
}
this.listone[$(targetElement).attr('id')].check = true
this.$forceUpdate()
} else {
this.listone.forEach(v => {
if (v.check) {
v.check = false
}
})
}
});
}
}
</script>
<style lang="less">
.content {
width: 100%;
height: 100%;
// border: 1px solid red;
background: blue;
span {
display: block;
width: 80px;
height: 50px;
line-height: 50px;
background: red;
border-radius: 5px;
margin: 5px;
text-align: center;
color: white;
font-size: 19px;
}
}
</style>
二级页面
<!--
* @LastEditTime: 2024-08-05 21:56:55
-->
<template>
<div
class="context-menu"
ref="containerRef"
:style="{
left: x + 'px',
top: y + 'px',
}"
>
<div class="menu-list">
<div
@click="handleClick(item)"
class="menu-item"
v-for="(item, i) in menu"
:key="i"
>{{ item.label }}</div>
</div>
</div>
</template>
<script >
export default {
props: ["menu", "x", "y"],
methods: {
handleClick() {
this.$emit("select")
}
},
}
</script>
<style lang="less" scoped>
.option {
width: 150px;
}
.context-menu {
position: fixed;
min-width: 150px;
box-sizing: border-box;
padding-top: 8px;
padding-bottom: 8px;
padding-left: 5px;
padding-right: 5px;
border-radius: 8px;
background: white;
.menu-item {
cursor: pointer;
border-radius: 4px;
padding: 5px;
}
.menu-item:hover {
cursor: pointer;
background: rgb(52, 119, 216);
color: white;
}
}
</style>