npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

vue3-menus

v1.1.2

Published

Vue3.0 左右键菜单

Downloads

1,439

Readme

vue3-menus

Vue3.0 自定义右键菜单,支持 Vite2.0,官网

Vue3.0 原生实现完全自定义右键菜单组件, 零依赖,可根据可视区域自动调节显示位置,可支持插槽完全重写每一项菜单

演示

在线演示

快速安装

npm 安装

npm install vue3-menus

yarn add vue3-menus

CDN

<script src="https://unpkg.com/vue3-menus/dist/vue3-menus.umd.min.js">

使用(Vite 情况下同样使用)

CDN引入则不需要 app.use(Vue3Menus)

样例中使用的是@ant-design/icons-vue图标与@element-plus/icons图标、图标可以使用html代码传入、也可以通过插槽自定义图标、也可以完全重写每一项菜单

// 全局注册组件、指令、方法
import { createApp } from 'vue';
import Menus from 'vue3-menus';
import App from './App.vue';
const app = createApp(App);
app.use(Menus);
app.mount('#app');
// 单个注册某个,以下三种方式均可在单个文件内使用
import { createApp } from 'vue';
import { directive, menusEvent, Vue3Menus } from 'vue3-menus';
import App from './App.vue';
const app = createApp(App);
app.component('vue3-menus', Vue3Menus); // 只注册组件
app.directive('menus', directive); // 只注册指令
app.config.globalProperties.$menusEvent = menusEvent; // 只绑定方法
app.mount('#app');
<template>
  <div style="height: 98vh; width: 100%;" v-menus:left="menus">
    <div class="div" v-menus:left="menus">指令方式打开菜单</div>
    <div class="div" @click.stop @contextmenu="($event) => $menusEvent($event, menus)">事件方式打开菜单</div>
    <div class="div" @click.stop @contextmenu="rightClick">组件方式打开菜单</div>
    <vue3-menus :open="isOpen" :event="eventVal" :menus="menus.menus">
      <template #icon="{menu, activeIndex, index}">{{activeIndex}}</template>
      <template #label="{ menu, activeIndex, index }">插槽:{{ menu.label }}</template>
    </vue3-menus>
  </div>
</template>
<script>
import { defineComponent, nextTick, ref, shallowRef } from "vue";
import { SyncOutlined, WindowsOutlined, QrcodeOutlined } from '@ant-design/icons-vue';
import { Printer } from '@element-plus/icons'

export default defineComponent({
  name: "App",
  setup() {
    const isOpen = ref(false);
    const eventVal = ref({});
    function rightClick(event) {
      isOpen.value = false;
      nextTick(() => {
        eventVal.value = event;
        isOpen.value = true;
      })
      event.preventDefault();
    }
    const menus = shallowRef({
      menus: [
        {
          label: "返回(B)",
          tip: 'Alt+向左箭头',
          click: () => {
            window.history.back(-1);
          }
        },
        {
          label: "点击不关闭菜单",
          tip: '不关闭菜单',
          click: () => {
            return false;
          }
        },
        {
          label: "前进(F)",
          tip: 'Alt+向右箭头',
          disabled: true
        },
        {
          label: "重新加载(R)",
          tip: 'Ctrl+R',
          click: () => location.reload(),
          divided: true
        },
        {
          label: "另存为(A)...",
          tip: 'Ctrl+S'
        },
        {
          label: "打印(P)...",
          tip: 'Ctrl+P',
          click: () => window.print(),
        },
        {
          label: "投射(C)...",
          divided: true
        },
        {
          label: '发送到你的设备',
          children: [
            {
              label: 'iPhone',
            },
            {
              label: 'iPad'
            },
            {
              label: 'Windows 11'
            }
          ]
        },
        {
          label: "为此页面创建二维码",
          divided: true,
        },
        {
          label: "使用网页翻译(F)",
          divided: true,
          children: [
            { label: "翻译成繁体中文" },
            { label: "翻译成繁体中文" },
            {
              label: "百度翻译", children: [
                { label: "翻译成繁体中文" },
                { label: "翻译成繁体中文" },]
            },
            {
              label: "搜狗翻译", children: [
                { label: "翻译成繁体中文" },
                { label: "翻译成繁体中文" },
              ]
            },
            {
              label: "有道翻译", children: [
                { label: "翻译成繁体中文" },
                { label: "翻译成繁体中文" },
              ]
            },
          ]
        },
        {
          label: "截取网页(R)"
        },
        { label: "查看网页源代码(U)", tip: 'Ctrl+U' },
        { label: "检查(N)", tip: 'Ctrl+Shift+I' }
      ]
    })
    return { menus, isOpen, rightClick, eventVal }
  },
});
</script>
.div {
  display: inline-block;
  background-color: aqua;
  margin: 0 20px;
  line-height: 200px;
  padding: 0 20px;
  height: 200px;
}

指令方式使用

<template>
  <div v-menus:left="menus">指令方式打开菜单</div>
</template>
<script>
import { defineComponent, shallowRef } from "vue";
import { directive } from 'vue3-menus';

export default defineComponent({
  name: "App",
  directives: {
    menus: directive
  },
  setup() {
    const menus = shallowRef({
      menus: [
        {
          label: "返回(B)",
          tip: 'Alt+向左箭头',
          click: () => {
            window.history.back(-1);
          }
        },
        {
          label: "点击不关闭菜单",
          tip: '不关闭菜单',
          click: () => {
            return false;
          }
        }
      ]
    })
    return { menus }
  },
});
</script>

方法方式使用

<template>
  <div class="div" @click.stop @contextmenu="rightClick">事件方式打开菜单</div>
</template>
<script>
import { defineComponent, shallowRef } from "vue";
import { menusEvent } from 'vue3-menus';

export default defineComponent({
  name: "App",
  setup() {
    const menus = shallowRef({
      menus: [
        {
          label: "返回(B)",
          tip: 'Alt+向左箭头',
          click: () => {
            window.history.back(-1);
          }
        },
        {
          label: "点击不关闭菜单",
          tip: '不关闭菜单',
          click: () => {
            return false;
          }
        }
      ]
    });
    function rightClick(event) {
      menusEvent(event, menus.value);
      event.preventDefault();
    }
    return { rightClick }
  },
});
</script>

组件方式使用

<template>
  <div class="div" @click.stop @contextmenu="rightClick">组件方式打开菜单</div>
  <vue3-menus v-model:open="isOpen" :event="eventVal" :menus="menus" hasIcon>
    <template #icon="{menu, activeIndex, index}">{{activeIndex}}</template>
    <template #label="{ menu, activeIndex, index}">插槽:{{ menu.label }}</template>
  </vue3-menus>
</template>
<script>
import { defineComponent, nextTick, ref, shallowRef } from "vue";
import { Vue3Menus } from 'vue3-menus';

export default defineComponent({
  name: "App",
  components: {
    Vue3Menus
  },
  setup() {
    const isOpen = ref(false);
    const eventVal = ref({});
    function rightClick(event) {
      isOpen.value = false;
      nextTick(() => {
        eventVal.value = event;
        isOpen.value = true;
      })
      event.preventDefault();
    }
    const menus = shallowRef([
      {
        label: "返回(B)",
        tip: 'Alt+向左箭头',
        click: () => {
          window.history.back(-1);
        }
      },
      {
        label: "点击不关闭菜单",
        tip: '不关闭菜单',
        click: () => {
          return false;
        }
      }
    ]);
    return { menus, isOpen, rightClick, eventVal }
  },
});
</script>

参数说明

单个菜单项参数MenusItemOptions

| 属性 | 描述 | 类型 | 是否必填 | 默认值 | | :------: | :----------------------------------------------------------: | :--------------------: | :------: | :---------: | | label | 菜单项名称 | string | true | — | | style | 每一项菜单的自定义样式 | object | false | {} | | icon | 图标参数,内部支持html字符串图标,传入组件时需要实现icon插槽 | string | 其他类型 | false | undefined | | disabled | 是否禁用菜单项 | boolean | false | undefined | | divided | 是否显示分割线 | boolean | false | undefined | | tip | 没项菜单后面的小提示 | string | false | '' | | hidden | 是否隐藏该项 | boolean | false | undefined | | children | 子菜单列表信息 | MenusItemOptions[] | false | undefined | | enter | 菜单项移入事件,返回nullfalse不展开子菜单 | Function() | false | undefined | | click | 菜单项点击事件,返回nullfalse不关闭菜单 | Function() | false | undefined |

指令与方法使用参数

| 属性 | 描述 | 类型 | 是否必填 | 默认值 | | :-------: | :---------------------------------------------: | :-------------------: | :------: | :---------: | | menus | 菜单列表信息 | MenusItemOptions[] | true | [] | | menusClass | 菜单外层 divclass 名 | string | false | null | | itemClass | 菜单每一项的class名 | string | false | null | | minWidth | 菜单容器最小宽度 | number | string | false | none | | maxWidth | 菜单容器最打宽度 | number | string | false | none | | zIndex | 菜单层级 | number | string | false | 3 | | direction | 菜单打开方向 | left | right | false | right |

组件使用参数

| 属性 | 描述 | 类型 | 是否必填 | 默认值 | 插槽传入值 | | :-------: | :---------------------------------------------: | :-------------------: | :------------------: | :---------: | :-----------------------------------------------: | | menus | 菜单列表信息 | MenusItemOptions[] | true | [] | | | event | 鼠标事件信息(指令使用时不传) | Event | 与position必填一项 | {} | | | menusClass | 菜单外层 divclass 名 | string | false | null | | | itemClass | 菜单每一项的class名 | string | false | null | | | minWidth | 菜单容器最小宽度 | number | string | false | none | | | maxWidth | 菜单容器最打宽度 | number | string | false | none | | | zIndex | 菜单层级 | number | string | false | 3 | | | direction | 菜单打开方向 | left | right | false | right | | | open | 控制菜单组件显示 | boolean | true | false | | | args | 附加参数 | unknown | false | undefined | | | default | 默认插槽 | Slot | false | - | activeIndex: 当前选中索引, menu: 当前菜单项 MenusItemOptions, index: 当前菜单索引 | | icon | 图标插槽 | Slot | false | - | activeIndex: 当前选中索引, menu: 当前菜单项 MenusItemOptions, index: 当前菜单索引 | | label | 菜单标题插槽 | Slot | false | - | activeIndex: 当前选中索引, menu: 当前菜单项 MenusItemOptions, index: 当前菜单索引 | | suffix | 菜单后缀插槽 | Slot | false | - | activeIndex: 当前选中索引, menu: 当前菜单项 MenusItemOptions, index: 当前菜单索引 |

指令使用配置

配置参数与方法使用相同

| 指令使用方式 | 描述 | 参数类型 | 参数是否必填 | 默认值 | | :-----------: | :------------------------: | :-----------: | :----------: | :----: | | v-menus | 绑定元素右击打开菜单 | MenuOptions | true | - | | v-menus:all | 绑定元素左右击均可打开菜单 | MenuOptions | true | - | | v-menus:left | 绑定元素左击打开 | MenuOptions | true | - | | v-menus:right | 绑定元素右击打开 | MenuOptions | true | - |