原生Vue 实现右键菜单组件功能

yizhihongxing

下面是详细的“原生Vue 实现右键菜单组件功能”的攻略:

1. 准备工作

要实现右键菜单组件,我们首先要准备好 Vue 以及相关依赖包,这里我以安装 Vue 3.x 版本为例。

在控制台运行以下命令:

npm install vue@next

另外,我们需要使用 popper.js 依赖库来实现菜单的弹出和定位,通过以下命令安装:

npm install @popperjs/core

2. 创建右键菜单组件

接下来,我们可以创建一个名为 ContextMenu.vue 的 Vue 单文件组件,并在其中编写右键菜单的 HTML 结构和样式。以下是一个简单的示例:

<template>
  <div class="context-menu" :style="{ top: position.top + 'px', left: position.left + 'px' }">
    <ul>
      <li v-for="(item, index) in items" :key="index" @click="item.action">{{ item.label }}</li>
    </ul>
  </div>
</template>

<script>
import { onMounted, onUnmounted, ref } from 'vue';
import { createPopper } from '@popperjs/core';

export default {
  props: {
    items: {
      type: Array,
      default: () => [],
    },
    position: {
      type: Object,
      default: () => ({ top: 0, left: 0 }),
    },
  },
  setup(props) {
    const reference = ref(null);
    const popper = ref(null);

    onMounted(() => {
      popper.value = createPopper(reference.value, props.position, {
        placement: 'right-start',
      });
    });

    onUnmounted(() => {
      popper.value.destroy();
      popper.value = null;
    });

    return {
      reference,
      popper,
    };
  },
};
</script>

<style scoped>
.context-menu {
  position: fixed;
  z-index: 999;
  background: white;
  border: 1px solid #ccc;
  list-style: none;
  padding: 0;
  margin: 0;
}

.context-menu ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.context-menu li {
  padding: 8px 12px;
  cursor: pointer;
}
.context-menu li:hover {
  background: #f2f2f2;
}
</style>

在这个示例中,我们使用了 Popper.js 实现了菜单的定位和弹出,同时在 props 中接收菜单项数据 items 和菜单位置信息 position,并根据数据动态生成菜单项的内容。

3. 在页面中使用右键菜单组件

实现菜单组件之后,我们需要在业务页面中使用该组件。以下是一个简单的示例:

<template>
  <div @contextmenu.prevent="showContextMenu" @click="hideContextMenu">
    <p>
      右键点击此处
    </p>
    <ContextMenu v-if="isContextMenuVisible" :position="contextMenuPosition" :items="contextMenuItems" />
  </div>
</template>

<script>
import ContextMenu from './ContextMenu.vue';

export default {
  components: {
    ContextMenu,
  },
  data() {
    return {
      isContextMenuVisible: false,
      contextMenuPosition: { top: 0, left: 0 },
      contextMenuItems: [
        {
          label: '菜单项1',
          action: () => {
            console.log('点击了菜单项1');
          },
        },
        {
          label: '菜单项2',
          action: () => {
            console.log('点击了菜单项2');
          },
        },
      ],
    };
  },
  methods: {
    showContextMenu(e) {
      this.isContextMenuVisible = true;
      this.contextMenuPosition = { top: e.clientY, left: e.clientX };
    },
    hideContextMenu() {
      this.isContextMenuVisible = false;
    },
  },
};
</script>

在这个示例中,我们在父组件的根元素上绑定了 contextmenu 事件,并传入了一个预设方法 showContextMenu,使右键点击事件被触发时,动态计算菜单位置和菜单项数据,并将变量 isContextMenuVisible 设置为 true,从而显示菜单。同时,在 click 事件中调用 hideContextMenu 方法,以隐藏菜单。

我们在页面中使用创建的 ContextMenu 组件,并传入菜单项数据 contextMenuItems 和位置信息 contextMenuPosition,这些信息都是在 showContextMenu 方法中动态计算得到的。

4. 添加菜单项动态更新的示例

接下来我们添加一个菜单项动态更新的示例,当菜单项数据发生变化时,菜单项应该自动更新。

我们可以在父组件中添加一个 data 属性 menuItemsUpdated,并在 mounted 生命钩子中创建一个定时器,每隔一段时间更新菜单项数据:

<template>
  <div @contextmenu.prevent="showContextMenu" @click="hideContextMenu">
    <p>
      右键点击此处
    </p>
    <ContextMenu v-if="isContextMenuVisible" :position="contextMenuPosition" :items="contextMenuItems" />
  </div>
</template>

<script>
import ContextMenu from './ContextMenu.vue';

export default {
  components: {
    ContextMenu,
  },
  data() {
    return {
      isContextMenuVisible: false,
      contextMenuPosition: { top: 0, left: 0 },
      contextMenuItems: [
        {
          label: '菜单项1',
          action: () => {
            console.log('点击了菜单项1');
          },
        },
        {
          label: '菜单项2',
          action: () => {
            console.log('点击了菜单项2');
          },
        },
      ],
      menuItemsUpdated: false,
    };
  },
  mounted() {
    setInterval(() => {
      const newItems = [
        {
          label: '菜单项1(已更新)',
          action: () => {
            console.log('点击了菜单项1(已更新)');
          },
        },
        {
          label: '菜单项2(已更新)',
          action: () => {
            console.log('点击了菜单项2(已更新)');
          },
        },
      ];
      this.contextMenuItems = newItems;
      this.menuItemsUpdated = !this.menuItemsUpdated;
    }, 5000);
  },
  methods: {
    showContextMenu(e) {
      this.isContextMenuVisible = true;
      this.contextMenuPosition = { top: e.clientY, left: e.clientX };
    },
    hideContextMenu() {
      this.isContextMenuVisible = false;
    },
  },
};
</script>

这个示例中,我们使用 setInterval 创建了一个定时器,在每次定时器回调中重新设置菜单项数据,并且每次 data 中的 menuItemsUpdated 属性值都会改变,这样就能触发组件的重新渲染和列表的更新。

注意:由于使用了 data 中的属性修改触发更新的方式,因此 contextMenuItems 的初始化应该使用函数的方式,即 default: () => []

总结

以上就是实现右键菜单组件的完整攻略,包含组件的创建、样式与事件的处理,以及在页面中的应用和菜单项动态更新的示例。通过实现上述内容,我们可以轻松实现自定义的右键菜单功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:原生Vue 实现右键菜单组件功能 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • wxappunpacker如何使用

    wxappunpacker如何使用 如果你有一个微信小程序(WeChat Applet)的源代码包,并想要查看它的结构,了解其内部实现、资源文件和代码,那么可以使用wxappunpacker工具来解压和检查小程序包。 安装wxappunpacker wxappunpacker是一个由Python编写的工具,可以直接从官方的Github仓库中下载和使用。首先,…

    其他 2023年3月29日
    00
  • 如何分析hprof文件

    如何分析hprof文件 背景 hprof文件是Java虚拟机(JVM)生成的一种堆转储文件(heap dump),它记录了 JVM 中各个对象在堆中的分布情况以及各个对象的属性情况。在排除Java应用程序内存问题时,hprof文件是一个重要的工具。本文将探讨如何分析hprof文件以解决Java应用程序的内存问题。 步骤 1. 生成hprof文件 在Java应…

    其他 2023年3月28日
    00
  • Android Oss上传图片的使用示例

    Android OSS上传图片的使用示例 概述 阿里云对象存储服务(OSS)是阿里云提供的一种简单可靠、低成本、高可扩展性的数据存储服务。该服务基于阿里云的海量分布式存储基础设施,通过Internet提供安全、稳定、高效、低延迟的数据访问和上传下载服务。 本文将详细讲解如何在Android应用中使用阿里云OSS上传图片。 前置条件 阿里云AccessKey …

    other 2023年6月27日
    00
  • string居然也可以用<<和>>

    当我们在C++中使用std::cin和std::cout进行输入输出时,它们采用了一种叫做流(stream)的输入输出机制,利用运算符重载,可以让字符串(string)类型也支持输入输出。 具体地说,我们可以使用std::cin机制来将标准输入流中的输入内容存储至字符串对象中,使用std::cout机制输出字符串对象的内容到标准输出流。 下面是使用std::…

    other 2023年6月20日
    00
  • vue实现一个懒加载的树状表格实例

    首先,我们需要明确什么是懒加载。懒加载即指仅当需要用到某个组件或数据时才进行加载,而不是一次性加载所有的数据和组件。在树状表格的场景中,懒加载指的是只有当节点被展开时才会加载子节点的数据。 接下来,我们将介绍如何使用vue实现一个懒加载的树状表格实例。 创建树状表格的基础组件 首先,我们需要创建一个基础的树状表格组件,包含展示数据所需要的功能,例如分页、排序…

    other 2023年6月27日
    00
  • React Hook Form 优雅处理表单使用指南

    React Hook Form 优雅处理表单使用指南 React Hook Form 是一个用于处理表单的库,它提供了一种优雅的方式来处理表单验证和表单状态管理。本攻略将详细介绍如何使用 React Hook Form。 安装 首先,我们需要安装 React Hook Form。可以使用 npm 或者 yarn 进行安装: npm install react…

    other 2023年7月28日
    00
  • Cypress系列(69)- route() 命令详解

    Cypress系列(69) – route() 命令详解 Cypress 是一个通过模拟真实浏览器环境来进行端到端测试的 JavaScript 测试框架。在测试中,我们经常需要模拟请求和响应。这时就需要使用 Cypress 的 route() 命令。 什么是 route() 命令? route() 命令是 Cypress 的一个命令,用于截获浏览器网络请求并…

    其他 2023年3月29日
    00
  • SpringBoot获取配置文件内容的几种方式总结

    对于“SpringBoot获取配置文件内容的几种方式总结”,我会给出详细讲解,具体如下: 一、配置文件的基本概念 在 SpringBoot 中,配置文件有两种格式:.properties 和 .yml。 .properties 格式 这是一种基于 key=value 形式构成的配置文件,其中每一行用等号(=)分隔成两部分,左侧是键(key),右侧是值(val…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部