我是靠谱客的博主 明亮哑铃,这篇文章主要介绍Vue3.0实现原生高度可自定义菜单组件vue3-menusvue3-menus,现在分享给大家,希望可以做个参考。

vue3-menus

Vue3.0 自定义右键菜单

Vue3.0 原生实现完全自定义右键菜单组件, 零依赖,可根据可视区域自动调节显示位置,可支持插槽完全重写每一项菜单

展示

项目地址

  • GitHub
  • Gitee

在线演示

  • 完整菜单功能演示
  • 复制粘贴演示

快速安装

npm 安装

复制代码
1
2
npm install vue3-menus

复制代码
1
2
yarn 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
6
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中进行别名替换

复制代码
1
2
3
4
5
6
import { 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
9
export default { resolve: { alias: { // 其他配置 'vue3-menus': 'https://esm.sh/vue3-menus@1.0.3'// 也可以将1.0.3换成其他版本号 } } }

参数说明

单个菜单项参数MenusItemOptions

属性描述类型是否必填默认值
label菜单项名称stringtrue
style每一项菜单的自定义样式objectfalse{}
iconstring: 传入图标html代码、object: 传入组件或者{node: 组件, option: 组件配置参数}string | objectfalseundefined
disabled是否禁用菜单项booleanfalseundefined
divided是否显示分割线booleanfalseundefined
tip没项菜单后面的小提示stringfalse''
click菜单项点击事件,返回nullfalse不关闭菜单Function()falseundefined
children子菜单列表信息MenusItemOptions[]falseundefined

公共参数MenuOptions

属性描述类型是否必填默认值
menus菜单列表信息MenusItemOptions[]true[]
menusStyle菜单容器的样式objectfalse{}
menusItemClass菜单每一项的classstringfalsenull
event鼠标事件信息(指令使用时可以不传)Eventposition必填一项{}
position手动传入菜单显示位置(指令使用时可以不传){x: number, y: number}event必填一项{}
minWidth菜单容器最小宽度number | stringfalsenone
maxWidth菜单容器最打宽度number | stringfalsenone
zIndex菜单层级number | stringfalse3

组件Vue3Menus参数

属性描述类型是否必填默认值插槽传入值
open控制菜单组件显示: v-model:openbooleantruefalsefalse
default默认插槽Slotfalse-activeIndex: 当前选中项, item: 当前菜单属性值
icon图标插槽Slotfalse-activeIndex: 当前选中项, item: 当前菜单属性值
label菜单标题插槽Slotfalse-activeIndex: 当前选中项, item: 当前菜单属性值
suffix菜单后缀插槽Slotfalse-activeIndex: 当前选中项, item: 当前菜单属性值

指令使用配置

指令使用方式描述参数类型参数是否必填默认值
v-menus绑定元素右击打开菜单MenuOptionstrue-
v-menus:all绑定元素左右击均可打开菜单MenuOptionstrue-
v-menus:left绑定元素左击打开MenuOptionstrue-
v-menus:right绑定元素右击打开MenuOptionstrue-

最后

以上就是明亮哑铃最近收集整理的关于Vue3.0实现原生高度可自定义菜单组件vue3-menusvue3-menus的全部内容,更多相关Vue3内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部