实现效果图
实现思路:
一、实现右击菜单的div
html内容
<div v-show="contextMenuVisible">
<ul :style="{left:menuLeft +'px',top:menuTop+'px'}" class="contextmenu">
<li><el-button type="text" @click="closeAll()" size="mini">关闭所有</el-button></li>
</ul>
</div>
- 用v-show控制显示和隐藏菜单盒子
- 给 关闭所有 绑定点击事件
二、CSS样式
.contextmenu {
width: 100px;
margin: 0;
border: 1px solid #ccc;
background: #fff;
z-index: 3000;
position: absolute;
list-style-type: none;
padding: 5px 0;
border-radius: 4px;
font-size: 14px;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.2);
}
.contextmenu li {
margin: 0;
padding: 0px 22px;
}
.contextmenu li:hover {
background: #f2f2f2;
cursor: pointer;
}
.contextmenu li button{
color: #2c3e50;
}
三、给tab绑定右击事件
由于不能直接在标签中绑定,所以需要在mounted中绑定
详细情况,如问题模块所示。
添加代码:
mounted() {
let tab_top_dom = document.getElementsByClassName('el-tabs__header is-top')
tab_top_dom[0].oncontextmenu = this.openContextMenu
}
四、实现右击弹出菜单栏事件
1.首先,在data()中添加控制显示隐藏的值
contextMenuVisible: false, //右键关闭显/隐藏
2.添加methods方法
//显示右击菜单(关闭所有)
openContextMenu(e){
e.preventDefault(); //防止默认菜单弹出
this.contextMenuVisible = true;
//返回鼠标坐标点,并传递给菜单的绝对定位值
this.menuLeft = e.clientX;
this.menuTop = e.clientY + 20;
},
//隐藏菜单
closeMenu(){/
this.contextMenuVisible = false
},
3.实现 关闭所有 功能
closeAll(){ // 关闭所有标签卡
this.tabsItem = [
{
title: '首页',
name: '1',
closable: false,
ref: 'tabs',
content: HomePage
}
];
this.activeTab = '1';
this.tabIndex = 1;
this.closeMenu(); //完成点击事件后,关闭菜单
},
五、监听点击事件,点击菜单以外的地方,实现菜单隐藏
在watch中添加
watch(){
contextMenuVisible() { //监听 右键关闭菜单 点击任何地方 菜单消失
if (this.contextMenuVisible) {
document.body.addEventListener("click", this.closeMenu);
} else {
document.body.removeEventListener("click", this.closeMenu);
}
},
}
遇到的问题:
1.直接对标签绑定右键点击事件,成功绑定,但是不仅tab标签部分绑定了,而且内容区域也绑定了,在整个tab区域内都可以右击实现菜单弹出
如下代码所示:
<el-tabs v-model="activeTab" type="card" @tab-remove="removeTab" @tab-click="tabClick"
@contextmenu.prevent.native="openContextMenu">
<el-tab-pane v-for="(item) in tabsItem"
:key="item.name"
:label="item.title"
:name="item.name"
:closable="item.closable"
:ref="item.ref"> >
<component :is="item.content"></component>
</el-tab-pane>
</el-tabs>
这样就没有浏览器默认的右击事件了,而且用户体验感很差,所以不能直接加到标签里
解决办法:
- 通过浏览器找到tab生成标签的class类名,精确定位需要右键事件的标签部分。
- 在页面加载完成之后,为其绑定右键事件
代码如下:
mounted() {// 使用原生js 为单个dom绑定鼠标右击事件
let tab_top_dom = document.getElementsByClassName('el-tabs__header is-top')
tab_top_dom[0].oncontextmenu = this.openContextMenu
}
*注:在vue中获取 dom可以使用ref的方式,但是本例中,Tab的标签部分,并非显式的出现在代码中,而是ElementUI框架内的部分,因此采用了原生的js方式。*
**2.解决vue中的报错[Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'preventDefault' of undefined"**
网址:解决办法
说明:
- 问题出的不太一样,但是解决方法管用
- 在mounted()里面调用函数时,多加了括号()
解决方案: 去掉即可
3. vue报错:Invalid prop: type check failed for prop "index". Expected String with value 解决方法: 原来是elementUI的:index字段为字符串格式,后台数据为num格式,格式警告,格式转换,问题解决!知识点:
1、CSS旋转45度
transform:rotate(45deg);
2、引入阿里巴巴矢量图标库
选择图标,加入购物车,下载代码压缩包
(1)Unicode 引用
1.解压后,把font文件夹copy到vue项目的公共文件目录下
2.在公共css文件中,加入以下代码
@font-face {
font-family: 'iconfont';
src: url('iconfont.ttf?t=1627459271213') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
3.挑选相应图标并获取字体编码,应用于页面
<span class="iconfont">3</span>
(2)font-class 引用
1.引入项目下生成的fontclass代码
<link rel="stylesheet" href="./iconfont.css">
2.挑选相应图标并获取类名,应用于页面
<span class="iconfont icon-xxx"></span>
参考项目地址:https://github.com/zhangjiangmse/back_menu.git
解决办法原地址:https://blog.csdn.net/qq_28200505/article/details/105791303