在前端开发中,自定义右键菜单是一种常见的交互方式,它能够为用户提供更多的功能选项。在本文中,将探讨如何在 vue 中实现一个动态右键菜单,该菜单能够根据用户点击位置动态调整其显示位置,确保菜单始终在浏览器窗口的可视区域内。
实现目标
- 右键点击页面时显示自定义菜单。
- 菜单根据点击位置动态定位。
- 确保菜单不会超出浏览器窗口的可视区域。(超出窗口顶部或者底部优化)
实现步骤
1. 创建 vue 组件模板
首先,编写 vue 组件的模板部分:
<template>
<div v-if="visible">
<a-menu class="contextmenu" :style="style" @click="handleclick">
<a-menu-item v-for="item in list" :key="item.key">
<span>{{ item.text }}</span>
</a-menu-item>
</a-menu>
</div>
</template>
在这个模板中,使用 v-if 指令控制菜单的显示与隐藏,并使用 :style 绑定菜单的动态样式。
2. 编写组件脚本
接下来是组件的脚本部分:
<script>
export default {
name: "contextmenu",
props: {
visible: {
type: boolean,
default: false,
},
list: {
type: array,
required: true,
default: () => [],
},
},
data() {
return {
left: 0,
top: 0,
target: null,
};
},
computed: {
style() {
return {
left: this.left + "px",
top: this.top + "px",
};
},
},
created() {
const clickhandler = () => this.closemenu();
const contextmenuhandler = (e) => {
e.preventdefault();
this.setposition(e);
};
window.addeventlistener("click", clickhandler);
window.addeventlistener("contextmenu", contextmenuhandler);
this.$emit("hook:beforedestroy", () => {
window.removeeventlistener("click", clickhandler);
window.removeeventlistener("contextmenu", contextmenuhandler);
});
},
methods: {
closemenu() {
this.$emit("update:visible", false);
},
setposition(e) {
// 获取菜单的宽高
const menu = document.queryselector(".contextmenu");
const menuheight = menu.offsetheight;
// 获取窗口的可视高度
const windowheight = window.innerheight;
this.left = e.clientx;
// 计算菜单的上边位置
if (e.clienty + menuheight > windowheight) {
const top = e.clienty - menuheight;
if (top < 0) {
this.top = 0; // 确保菜单不会超出顶部
} else {
// 如果菜单的底部超出了窗口的底部
this.top = top;
}
} else {
// 如果菜单的底部没有超出窗口的底部
this.top = e.clienty;
}
this.target = e.target;
},
handleclick({ key }) {
const _component = this.list.filter((item) => item.key === key)[0]
.component;
if (_component) {
this.$emit("contextmenuclick", _component, key);
}
this.closemenu();
},
},
};
</script>
详细解释
setposition 方法
setposition 方法用于根据用户点击的位置动态调整菜单的位置,确保菜单始终在可视区域内。
setposition(e) {
// 获取菜单的宽高
const menu = document.queryselector(".contextmenu");
const menuheight = menu.offsetheight;
// 获取窗口的可视高度
const windowheight = window.innerheight;
this.left = e.clientx;
// 计算菜单的上边位置
if (e.clienty + menuheight > windowheight) {
const top = e.clienty - menuheight;
if (top < 0) {
this.top = 0; // 确保菜单不会超出顶部
} else {
// 如果菜单的底部超出了窗口的底部
this.top = top;
}
} else {
// 如果菜单的底部没有超出窗口的底部
this.top = e.clienty;
}
this.target = e.target;
}
- 相加:通过
e.clienty + menuheight计算菜单底部的位置,如果大于windowheight,则表示菜单超出了窗口底部,需要调整位置。 - 相减:通过
e.clienty - menuheight将菜单位置调整到鼠标点击位置的上方,确保菜单不会超出窗口底部。 - clienty:鼠标点击位置的垂直坐标,相对于视口。
- offsetheight:菜单元素的高度,包括内容的高度、内边距和边框。
事件处理
在 created 生命周期钩子中,添加了 click 和 contextmenu 事件监听器。
created() {
const clickhandler = () => this.closemenu();
const contextmenuhandler = (e) => {
this.setposition(e);
};
window.addeventlistener("click", clickhandler);
window.addeventlistener("contextmenu", contextmenuhandler);
this.$emit("hook:beforedestroy", () => {
window.removeeventlistener("click", clickhandler);
window.removeeventlistener("contextmenu", contextmenuhandler);
});
}
- clickhandler:点击页面时,关闭菜单。
- contextmenuhandler:右键点击时,阻止默认的右键菜单行为,并根据点击位置设置菜单的位置。
样式部分
<style lang="scss" scoped>
.contextmenu {
position: fixed;
z-index: 1000;
border-radius: 4px;
border: 1px lightgrey solid;
box-shadow: 4px 4px 10px lightgrey !important;
}
</style>
总结
通过以上代码,实现了一个动态右键菜单。这个菜单能够根据用户的点击位置动态调整其显示位置,确保菜单始终在浏览器窗口的可视区域内。这样的实现可以提升用户体验,使应用更加友好和易用。
到此这篇关于vue中实现动态右键菜单的示例代码的文章就介绍到这了,更多相关vue 动态右键菜单内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论