2 Star 18 Fork 9

xfy520 / vue3-menus

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

vue3-menus

Vue3.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">

使用

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 v-model:open="isOpen" :event="eventVal" :menus="menus.menus" hasIcon>
      <template #icon="{item: {activeIndex}}">{{activeIndex}}</template>
      <template #label="{ item: { item } }">插槽:{{ item.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',
          icon: {
            node: SyncOutlined,
            option: {
              spin: true
            }
          },
          click: () => location.reload(),
          divided: true
        },
        {
          label: "另存为(A)...",
          tip: 'Ctrl+S'
        },
        {
          label: "打印(P)...",
          tip: 'Ctrl+P',
          icon: {
            node: Printer,
            option: {
              color: 'red'
            }
          },
          click: () => window.print(),
        },
        {
          label: "投射(C)...",
          divided: true
        },
        {
          label: '发送到你的设备',
          icon: WindowsOutlined,
          children: [
            {
              label: 'iPhone',
            },
            {
              label: 'iPad'
            },
            {
              label: 'Windows 11'
            }
          ]
        },
        {
          label: "为此页面创建二维码",
          divided: true,
          icon: {
            node: QrcodeOutlined,
            option: {
              style: {
                color: 'aqua'
              }
            }
          }
        },
        {
          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="{item: {activeIndex}}">{{activeIndex}}</template>
    <template #label="{ item: { item } }">插槽:{{ item.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>

Vite下使用

使用方式1

import { createApp } from 'vue';
import App from './App.vue';
import Vue3Menus from 'https://esm.sh/vue3-menus@1.0.3'; // 也可以将1.0.3换成其他版本号
const app = createApp(App);
app.mount('#app');

使用方式2

在vite配置文件vite.config中进行别名替换

import { createApp } from 'vue';
import App from './App.vue';
import Vue3Menus from 'vue3-menus';
const app = createApp(App);
app.mount('#app');
export default {
  resolve: {
    alias: {
      // 其他配置
      'vue3-menus': 'https://esm.sh/vue3-menus@1.0.3'// 也可以将1.0.3换成其他版本号
    }
  }
}

参数说明

单个菜单项参数MenusItemOptions

属性 描述 类型 是否必填 默认值
label 菜单项名称 string true
style 每一项菜单的自定义样式 object false {}
icon string: 传入图标html代码、object: 传入组件或者{node: 组件, option: 组件配置参数} string | object false undefined
disabled 是否禁用菜单项 boolean false undefined
divided 是否显示分割线 boolean false undefined
tip 没项菜单后面的小提示 string false ''
click 菜单项点击事件,返回nullfalse不关闭菜单 Function() false undefined
children 子菜单列表信息 MenusItemOptions[] false undefined

公共参数MenuOptions

属性 描述 类型 是否必填 默认值
menus 菜单列表信息 MenusItemOptions[] true []
menusStyle 菜单容器的样式 object false {}
menusItemClass 菜单每一项的class string false null
event 鼠标事件信息(指令使用时可以不传) Event position必填一项 {}
position 手动传入菜单显示位置(指令使用时可以不传) {x: number, y: number} event必填一项 {}
minWidth 菜单容器最小宽度 number | string false none
maxWidth 菜单容器最打宽度 number | string false none
zIndex 菜单层级 number | string false 3

组件Vue3Menus参数

属性 描述 类型 是否必填 默认值 插槽传入值
open 控制菜单组件显示 boolean true false false
default 默认插槽 Slot false - activeIndex: 当前选中项, item: 当前菜单属性值
icon 图标插槽 Slot false - activeIndex: 当前选中项, item: 当前菜单属性值
label 菜单标题插槽 Slot false - activeIndex: 当前选中项, item: 当前菜单属性值
suffix 菜单后缀插槽 Slot false - activeIndex: 当前选中项, item: 当前菜单属性值

指令使用配置

指令使用方式 描述 参数类型 参数是否必填 默认值
v-menus 绑定元素右击打开菜单 MenuOptions true -
v-menus:all 绑定元素左右击均可打开菜单 MenuOptions true -
v-menus:left 绑定元素左击打开 MenuOptions true -
v-menus:right 绑定元素右击打开 MenuOptions true -
MIT License Copyright (c) 2021 xfy520 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

Vue3.0 自定义右键菜单 展开 收起
NodeJS
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
NodeJS
1
https://gitee.com/longxinziyan/vue3-menus.git
git@gitee.com:longxinziyan/vue3-menus.git
longxinziyan
vue3-menus
vue3-menus
master

搜索帮助