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 returnnull orfalse Do 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 menuclass The name |
string |
false |
null |
event | Mouse event information (instructions can be used without transmission) | Event |
withposition Will fill a |
{} |
position | Manual input menu display position (instruction can not be transmitted when using) | {x: number, y: number} |
withevent Will 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 |
componentVue3Menus
parameter
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 |
– |