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 | 菜单项点击事件,返回 null 或false 不敞开菜单 |
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 | 管制菜单组件显示: v-model: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 |
– |