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 | - |