Vue中实现动态右键菜单的示例代码

 更新时间:2024年11月08日 09:52:02   作者:ZJ_.  
在前端开发中,实现自定义右键菜单能够为用户提供更多功能选项,本文就来介绍了Vue中实现动态右键菜单的示例代码,感兴趣的可以了解一下

在前端开发中,自定义右键菜单是一种常见的交互方式,它能够为用户提供更多的功能选项。在本文中,将探讨如何在 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 动态右键菜单内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue 插件及浏览器本地存储

    Vue 插件及浏览器本地存储

    这篇文章主要介绍了Vue 插件及浏览器本地存储,插件通常用来为Vue添加全局功能,包含install方法的一个对象。更多相关介绍,需要的小伙伴可以参考下面文章内容
    2022-05-05
  • 在导入.vue文件的时候,ts报错提示:找不到模块“@/Layout/index.vue”或其相应的类型声明问题

    在导入.vue文件的时候,ts报错提示:找不到模块“@/Layout/index.vue”或其相应的类型声明问题

    这篇文章主要介绍了在导入.vue文件的时候,ts报错提示:找不到模块“@/Layout/index.vue”或其相应的类型声明问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • vue中使用Axios最佳实践方式

    vue中使用Axios最佳实践方式

    Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js,Axios 使用简单,包尺寸小且提供了易于扩展的接口,这篇文章主要介绍了vue中使用Axios最佳实践,需要的朋友可以参考下
    2022-09-09
  • 使用Vue-cli 3.0搭建Vue项目的方法

    使用Vue-cli 3.0搭建Vue项目的方法

    这篇文章主要介绍了使用Vue-cli 3.0搭建Vue项目的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • 学习Vite的原理

    学习Vite的原理

    这篇文章主要介绍了Vite的原理,Vite是一个更轻、更快的web应用开发工具,面向现代浏览,Vite创建的项目是一个普通的Vue3应用,相比基于Vue-cli创建的应用少了很多配置文件和依赖,下面基于Vite相关资料内容,需要的朋友可以参考一下
    2022-02-02
  • Vue.js中动态更改svg的相关属性详解

    Vue.js中动态更改svg的相关属性详解

    这篇文章主要为大家介绍了Vue.js中动态更改svg的相关属性详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Vue 项目代理设置的优化

    Vue 项目代理设置的优化

    这篇文章主要介绍了Vue 项目代理设置的优化功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2018-04-04
  • vue keep-alive 动态删除组件缓存的例子

    vue keep-alive 动态删除组件缓存的例子

    今天小编就为大家分享一篇vue keep-alive 动态删除组件缓存的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • 解决vue创建项目使用vue-router和vuex报错Object(...)is not a function

    解决vue创建项目使用vue-router和vuex报错Object(...)is not a&nb

    这篇文章主要介绍了解决vue创建项目使用vue-router和vuex报错Object(...)is not a function问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • vue中keep-alive组件使用和一些基础配置方法

    vue中keep-alive组件使用和一些基础配置方法

    本文主要介绍了Vue中keep-alive组件的使用方法和一些基础配置,keep-alive是Vue中的一个抽象组件,可以缓存组件实例,提高性能,本文给大家介绍vue中keep-alive组件使用和一些基础配置方法,感兴趣的朋友一起看看吧
    2024-10-10

最新评论