vue3-menus

Vue3.0 Custom right-click menu

Vue3.0 native implementation completely custom right-click menu components, zero dependence, can automatically adjust the display position according to the visual area, can support the slot to completely rewrite each menu

The project address

  • GitHub
  • Gitee

The online demo

  • Complete menu function demonstration
  • Copy and paste demo

Fast installation

NPM install

npm install vue3-menus
Copy the code

or

yarn add vue3-menus
Copy the code

CDN

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

use

Do not use(Vue3Menus) with CDN

The example uses the @ant-Design /icons-vue and @element-plus/ ICONS ICONS. ICONS can be passed in using HTML code, custom ICONS can be inserted through slots, or each menu can be completely rewritten

// Globally register components, directives, methods
import { createApp } from 'vue';
import Menus from 'vue3-menus';
import App from './App.vue';
const app = createApp(App);
app.use(Menus);
app.mount('#app');
The following three methods can be used in a single file
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); // Only components are registered
app.directive('menus', directive); // Only register directives
app.config.globalProperties.$menusEvent = menusEvent; // bind only methods
app.mount('#app');
Copy the code
<template>
  <div style="height: 98vh; width: 100%;" v-menus:left="menus">
    <div class="div" v-menus:left="menus">Command mode opens the menu</div>
    <div class="div" @click.stop @contextmenu="($event) => $menusEvent($event, menus)">Event mode opens the menu</div>
    <div class="div" @click.stop @contextmenu="rightClick">Open the menu in component mode</div>
    <vue3-menus v-model:open="isOpen" :event="eventVal" :menus="menus.menus" hasIcon>
      <template #icon="{item: {activeIndex}}">{{activeIndex}}</template>
      <template #label="{ item: { item } }">Slot: {{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: "Return to (B)".tip: 'Alt+ left arrow '.click: () = > {
            window.history.back(-1); }}, {label: "Click don't close menu".tip: 'Do not close menu'.click: () = > {
            return false; }}, {label: "Forward (F)".tip: 'Alt+ arrow to right '.disabled: true
        },
        {
          label: "Reload (R)".tip: 'Ctrl+R'.icon: {
            node: SyncOutlined,
            option: {
              spin: true}},click: () = > location.reload(),
          divided: true
        },
        {
          label: "Save as (A)...".tip: 'Ctrl+S'
        },
        {
          label: "Print (P)...".tip: 'Ctrl+P'.icon: {
            node: Printer,
            option: {
              color: 'red'}},click: () = > window.print(),
        },
        {
          label: "The projection (C)...".divided: true
        },
        {
          label: 'Send to your device'.icon: WindowsOutlined,
          children: [{label: 'iPhone'}, {label: 'iPad'
            },
            {
              label: 'Windows 11'}]}, {label: "Create a QR code for this page".divided: true.icon: {
            node: QrcodeOutlined,
            option: {
              style: {
                color: 'aqua'}}}}, {label: "Using web page translation (F)".divided: true.children: [{label: "Translated into Traditional Chinese" },
            { label: "Translated into Traditional Chinese" },
            {
              label: "Baidu Translate".children: [{label: "Translated into Traditional Chinese" },
                { label: "Translated into Traditional Chinese"]}, {},label: "Sogou Translation".children: [{label: "Translated into Traditional Chinese" },
                { label: "Translated into Traditional Chinese"]}, {},label: "Youdao Translation".children: [{label: "Translated into Traditional Chinese" },
                { label: "Translated into Traditional Chinese"},]},]}, {label: "Web Page Capture (R)"
        },
        { label: "View page source code (U)".tip: 'Ctrl+U' },
        { label: "Check (N)".tip: 'Ctrl+Shift+I'}]})return { menus, isOpen, rightClick, eventVal }
  },
});
</script>
Copy the code
.div {
  display: inline-block;
  background-color: aqua;
  margin: 0 20px;
  line-height: 200px;
  padding: 0 20px;
  height: 200px;
}
Copy the code

Instruction mode use

<template>
  <div v-menus:left="menus">Command mode opens the menu</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: "Return to (B)".tip: 'Alt+ left arrow '.click: () = > {
            window.history.back(-1); }}, {label: "Click don't close menu".tip: 'Do not close menu'.click: () = > {
            return false; }}}])return { menus }
  },
});
</script>
Copy the code

Method mode use

<template>
  <div class="div" @click.stop @contextmenu="rightClick">Event mode opens the menu</div>
</template>
<script>
import { defineComponent, shallowRef } from "vue";
import { menusEvent } from 'vue3-menus';

export default defineComponent({
  name: "App".setup() {
    const menus = shallowRef({
      menus: [{label: "Return to (B)".tip: 'Alt+ left arrow '.click: () = > {
            window.history.back(-1); }}, {label: "Click don't close menu".tip: 'Do not close menu'.click: () = > {
            return false; }}});function rightClick(event) {
      menusEvent(event, menus.value);
      event.preventDefault();
    }
    return { rightClick }
  },
});
</script>
Copy the code

Component mode

<template>
  <div class="div" @click.stop @contextmenu="rightClick">Open the menu in component mode</div>
  <vue3-menus v-model:open="isOpen" :event="eventVal" :menus="menus" hasIcon>
    <template #icon="{item: {activeIndex}}">{{activeIndex}}</template>
    <template #label="{ item: { item } }">Slot: {{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: "Return to (B)".tip: 'Alt+ left arrow '.click: () = > {
          window.history.back(-1); }}, {label: "Click don't close menu".tip: 'Do not close menu'.click: () = > {
          return false; }}]);return { menus, isOpen, rightClick, eventVal }
  },
});
</script>
Copy the code

Vite use

Mode of use 1

import { createApp } from 'vue';
import App from './App.vue';
import Vue3Menus from 'https://esm.sh/[email protected]'; // You can also change 1.0.3 to another version number
const app = createApp(App);
app.mount('#app');
Copy the code

Usage 2

Alias replacement is performed in the vite configuration file vite. Config

import { createApp } from 'vue';
import App from './App.vue';
import Vue3Menus from 'vue3-menus';
const app = createApp(App);
app.mount('#app');
Copy the code
export default {
  resolve: {
    alias: {
      // Other configurations
      'vue3-menus': 'https://esm.sh/[email protected]'// You can also change 1.0.3 to another version number}}}Copy the code

Parameters that

Single menu item parameterMenusItemOptions

attribute describe type If required The default value
label Menu item name string true
style Custom styles for each menu item object false {}
icon string: Pass in the icon HTML code,object: Passes the component or{node: component, option: component configuration parameter} string | object false undefined
disabled Whether to disable menu items boolean false undefined
divided Whether to display the dividing line boolean false undefined
tip There are no tips at the back of the menu string false ' '
click Menu item click event to returnnullorfalseDo not close menu Function() false undefined
children Submenu list information MenusItemOptions[] false undefined

Public parametersMenuOptions

attribute describe type If required The default value
menus Menu List information MenusItemOptions[] true []
menusStyle Menu container style object false {}
menusItemClass For every item on the menuclassThe name string false null
event Mouse event information (instructions can be used without transmission) Event withpositionWill fill a {}
position Manual input menu display position (instruction can not be transmitted when using) {x: number, y: number} witheventWill fill a {}
minWidth Minimum width of menu container number | string false none
maxWidth Maximum menu container width number | string false none
zIndex The menu hierarchy number | string false 3

componentVue3Menusparameter

attribute describe type If required The default value Slot incoming value
open Control menu component display:v-model:open boolean true false false
default The default slot Slot false activeIndex: The currently selected item,item: Current menu property value
icon The icon in the slot Slot false activeIndex: The currently selected item,item: Current menu property value
label Menu title slot Slot false activeIndex: The currently selected item,item: Current menu property value
suffix Menu suffix slot Slot false activeIndex: The currently selected item,item: Current menu property value

Instruction usage configuration

Instruction usage mode describe The parameter types Parameter Specifies whether to specify this parameter The default value
v-menus Bind element right – click to open the menu MenuOptions true
v-menus:all Bind elements left or right click to open the menu MenuOptions true
v-menus:left Left-click to open the binding element MenuOptions true
v-menus:right Right-click to open the binding element MenuOptions true