vue3-menus
Vue3.0 自定义右键菜单
Vue3.0 原生实现完全自定义右键菜单组件, 零依赖,可根据可视区域自动调节显示位置,可支持插槽完全重写每一项菜单
项目地址
- GitHub
- Gitee
在线演示
- 完整菜单功能演示
- 复制粘贴演示
快速安装
npm 安装
复制代码
1
2npm install vue3-menus
或
复制代码
1
2yarn add vue3-menus
CDN
复制代码
1
2<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
代码传入、也可以通过插槽自定义图标
、也可以完全重写每一项菜单
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 全局注册组件、指令、方法 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');
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145<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>
复制代码
1
2
3
4
5
6
7
8
9.div { display: inline-block; background-color: aqua; margin: 0 20px; line-height: 200px; padding: 0 20px; height: 200px; }
指令方式使用
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36<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>
方法方式使用
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37<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>
组件方式使用
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48<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
复制代码
1
2
3
4
5
6import { 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中进行别名替换
复制代码
1
2
3
4
5
6import { createApp } from 'vue'; import App from './App.vue'; import Vue3Menus from 'vue3-menus'; const app = createApp(App); app.mount('#app');
复制代码
1
2
3
4
5
6
7
8
9export 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 | - |
最后
以上就是明亮哑铃最近收集整理的关于Vue3.0实现原生高度可自定义菜单组件vue3-menusvue3-menus的全部内容,更多相关Vue3内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复