Vue 中实现动态右键菜单

在前端开发中,自定义右键菜单是一种常见的交互方式,它能够为用户提供更多的功能选项。在本文中,将探讨如何在 Vue 中实现一个动态右键菜单,该菜单能够根据用户点击位置动态调整其显示位置,确保菜单始终在浏览器窗口的可视区域内。

实现目标

  1. 右键点击页面时显示自定义菜单。
  2. 菜单根据点击位置动态定位。
  3. 确保菜单不会超出浏览器窗口的可视区域。(超出窗口顶部或者底部优化)

实现步骤

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 生命周期钩子中,添加了 clickcontextmenu 事件监听器。

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>

总结

通过以上代码,实现了一个动态右键菜单。这个菜单能够根据用户的点击位置动态调整其显示位置,确保菜单始终在浏览器窗口的可视区域内。这样的实现可以提升用户体验,使应用更加友好和易用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/41555.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Steam平台的辉煌轨迹:数字游戏革命的领航者

在数字世界的浩瀚星空中&#xff0c;有一颗恒星以其耀眼的光芒照亮了无数游戏爱好者的道路&#xff0c;它就是Valve公司的杰作——Steam平台。自2003年横空出世以来&#xff0c;Steam不仅颠覆了传统游戏分发的模式&#xff0c;更以其卓越的创新能力和前瞻性的战略眼光&#xff…

CSS - 深入理解选择器的使用方式

CSS基本选择器 通配选择器元素选择器类选择器id 选择器 通配选择器 作用&#xff1a;可以选中所有HTML元素。语法&#xff1a; * {属性名&#xff1b;属性值; }举例&#xff1a; /* 选中所有元素 */ * {color: orange;font-size: 40px; }在清除样式方面有很大作用 元素选择器…

JAVA基础知识(下)

一、String相关面试题 1. 为什么 String 在 java 中是不可变的? - 如果不是不可变的&#xff1a;这种情况根本不可能&#xff0c;因为在字符串池的情况下&#xff0c;一个字符串对象/文字&#xff0c;例如 “Test” 已被许多参考变量引用&#xff0c; 因此如果其中任何一个更…

ubuntu下载Nginx

一、Nginx下载安装&#xff08;Ubuntu系统&#xff09; 1.nginx下载 sudo apt-get install nginx2.nginx启动 启动命令 sudo nginx重新编译(每次更改完nginx配置文件后运行&#xff09;&#xff1a; sudo nginx -s reload3.测试nginx是否启动成功 打开浏览器访问本机80端口…

小酌消烦暑|人间正清欢

小暑是二十四节气之第十一个节气。暑&#xff0c;是炎热的意思&#xff0c;小暑为小热&#xff0c;还不十分热。小暑虽不是一年中最炎热的时节&#xff0c;但紧接着就是一年中最热的节气大暑&#xff0c;民间有"小暑大暑&#xff0c;上蒸下煮"之说。中国多地自小暑起…

openssh版本升级实战(修补ssh漏洞)基于RedHat8.4版本测试--已成功升级

升级前具有漏洞的的版本 通过命令查看目前系统的ssh和sshd版本&#xff1a; ssh -V sshd -V 注意&#xff1a;由于ssh是远程连接服务器的功能&#xff0c;在进行下面操作升级openssh前&#xff0c;请打开多个连接会话保持&#xff0c;如升级失败&#xff0c;可通过已连接的会话…

antd实现简易相册,zdppy+vue3+antd实现前后端分离相册

前端代码 <template><a-image:preview"{ visible: false }":width"200"src"http://localhost:8889/download/1.jpg"click"visible true"/><div style"display: none"><a-image-preview-group:previe…

粤港澳大湾区人工智能资本对接会”成功举办!

为促进惠州仲恺高新区人工智能产业的发展&#xff0c;推动惠深两地产业资源深度协同与合作&#xff0c;也为吸引更多的优质项目与投融资机构为惠州仲恺高新区产业发展注入动力&#xff0c;加速深圳人工智能相关产业资源落地仲恺。2024年06月26日&#xff0c;由仲恺高新区科技创…

GNU/Linux - wic文件的使用

Yocto/OpenEmbedded使用的磁盘镜像格式是 wic。为嵌入式系统提供 bootable images。 The disk image format used in the Yocto Project is wic. .wic 文件显然只是一个带有分区表和分区的磁盘镜像&#xff0c;就像下载 Linux 发行版时获得的所有 .img 文件一样。这就是为什么你…

Laravel配置宝典:探索配置文件的深度使用

标题&#xff1a;Laravel配置宝典&#xff1a;探索配置文件的深度使用 Laravel框架的配置文件是管理应用设置的强大工具&#xff0c;它们使得开发者能够轻松地调整应用的行为&#xff0c;而无需修改代码。这些配置文件以PHP数组的形式存储&#xff0c;易于理解和修改。本文将详…

UE5 视频播放(自动播放和自动清除MediaTexture)

媒体播放器的打开时播放和媒体纹理的自动清除 。 在UE5开发视频播放时&#xff0c;遇到了闪帧的现象。合理选择这两个功能可解决。

小阿轩yx-LVS+Keepalived群集

小阿轩yx-LVSKeepalived群集 Keepalived 双机热备份基础知识 起初是专门针对 LVS 设计的一款强大的辅助工具主要用来提供故障切换(Failover)和健康检査(HealthChecking)功能—判断LVS 负载调度器、节点服务器的可用性当 master 主机出现故障及时切换到backup 节点保证业务正常…

动手学深度学习(Pytorch版)代码实践 -循环神经网络-51序列模型

51序列模型 import torch from torch import nn from d2l import torch as d2l import matplotlib.pyplot as pltT 1000 # 总共产生1000个点 time torch.arange(1, T 1, dtypetorch.float32) x torch.sin(0.01 * time) torch.normal(mean0, std0.2, size(T,)) d2l.plot(…

ERROR | Web server failed to start. Port 8080 was already in use.

错误提示&#xff1a; *************************** APPLICATION FAILED TO START ***************************Description:Web server failed to start. Port 8080 was already in use.Action:Identify and stop the process thats listening on port 8080 or configure thi…

Swagger的原理及应用详解(九)

本系列文章简介&#xff1a; 在当今快速发展的软件开发领域&#xff0c;特别是随着微服务架构和前后端分离开发模式的普及&#xff0c;API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;的设计与管理变得愈发重要。一个清晰、准确且易…

2024年特种设备(电梯作业)题库考试题库

1.直接作用式液压电梯轿厢与柱塞&#xff08;缸筒&#xff09;之间的连接应为&#xff08;&#xff09;。 A.刚性连接 B.固定连接 C.法兰连接 D.挠性连接 答案&#xff1a;D 2.正常情况下&#xff0c;当电磁式继电器线圈得电时&#xff0c;其常开触点将&#xff08;&…

Al Native应用中的模型微调

在AI Native应用中进行模型微调是一项关键的技术步骤&#xff0c;它允许预训练模型更好地适应特定的任务或数据集。为了更深入地理解AI Native应用中的模型微调&#xff0c;下面将从不同方面进行详细探讨&#xff1a; 微调过程的关键步骤 数据准备&#xff1a;微调开始之前&…

二进制求和、字符串相加-sting类题型

67. 二进制求和 - 力扣&#xff08;LeetCode&#xff09; 两个题目方法完全一样 用两个数据的末尾位相加&#xff0c;从末尾位开始逐位相加&#xff0c;记录进位&#xff1b; class Solution { public:string addBinary(string a, string b) {int end1 a.size() - 1;int end…

人工智能在招投标领域的运用---监控视频连续性检测

作者&#xff1a;舒城县公共交易中心 zhu_min726126.com 原创&#xff0c;转载请注明出处。 摘要 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;其在各个领域的应用日益广泛。本文旨在探讨人工智能在招投标领域的运营&#xff0c;重点介绍AI对视频完整…

ASUS/华硕飞行堡垒9 FX506H FX706H系列 原厂win10系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;一键恢复&#xff0c;以及机器所有驱动软件。 系统版本&#xff1a;Windows10 原厂系统下载网址&#xff1a;http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意&#xff1a;仅支持以上型号专用…