实现效果如下:
一、点击左边菜单,实现右边tabs列表的加载
-
我们已经将左边菜单栏跟tabs列表分别单独抽成组件。这里暂且将左边叫做
菜单组件(nav-menu.vue)
。右边顶部tabs这是又是一个组件我们暂且叫tabs组件(tags.vue)
很明显这两个兄弟组件是有交互的,点击菜单的时候要加载tabs列表。实现原理如下:
-
方式1
1.左侧菜单组件中每次点击的时候使用调用了tabs组件的方法,给tabs组件里面
tagsList
数组赋值。
2.模板遍历tagsList生成tab
其实这种方式有点小问题,耦合性有点高,涉及到了兄弟组件直接的交互.所以我们接下来看下方式2
-
方式2:原理如下
1、点击菜单组件的时候会跳转路由
2、我们在tabs组件里面其实可以监控路由变化,然后再做tabsList赋值操作等。这样就实现了两个组件间的解耦。代码后面会贴出来。
二、 实现右键弹出菜单,必须先要禁用浏览器默的右键菜单弹出,
利用contextmenu
事件阻止浏览器原生的菜单栏出现,然后绑定我们的显示菜单栏的自定义事件。在vue3中使用修饰符即可实现@contextmenu.prevent="setSelectedTag(item,$event)"
-
第一种右键弹出菜单我们自己写,不借助插件,稍微麻烦
我们先来看看tabs组件模板里面的内容
1.模板中整个ul就是右键菜单的内容了、contextMenuVisible控制右键菜单显示隐藏。:style
动态设置菜单显示的位置,因为我们要让他跟随每个tag附近显示
2.从模板中可以看到我们遍历了tagsList,给每个tag都禁用了默认的右键弹出菜单,并且绑定到了自定义事件setSelectedTag(item,$event)
中
接下来我们再看看js里面的关键部分:
data() {
return {
tagsList: [],
selectedTag: undefined, // 右键选中的tag
tagRefs: [],
contextMenuVisible: false, // 是否显示菜单
menuLeft: '', // 右键菜单距离浏览器左边的距离
menuTop: '' // 右键菜单距离浏览器上边的距离
}
},
setSelectedTag(tag,event) {
const e = event || window.event
const target = e.target
this.menuLeft = e.layerX + 20 + 'px' // 菜单出现的位置距离左侧的距离
this.menuTop = e.layerY + 20 + 'px' // 菜单出现的位置距离顶部的距离
this.contextMenuVisible = true // 显示菜单
this.selectedTag = tag// 当前右击的菜单信息
}
再看CSS部分
.right-menu{
width: 80px;
text-align: center;
position: absolute;
z-index: 100000;
border: 1px solid #ccc;
background: #f2f2f2;
border-radius: 5px;
padding: 5px;
font-size: 14px;
}
所以可以看到我们自己实现这个右键弹出菜单很繁琐是吧,主要是告诉大家如何不用插件去实现的思路而已。好了我们开始用我们的插件吧。
-
第二种使用ContextMenu component for Vue 3插件实现右键弹出菜单
[文档地址](https://vuejsexamples.com/contextmenu-component-for-vue-3/)
1.运行 $ npm i -S v-contextmenu@next 或者 yarn add v-contextmenu@next
安装完以后我们来直接上代码吧
tags.vue 完整代码
刷新页面
关闭当前
关闭其他
关闭所有
用于vuex 里面tags.js标签存储内容(用于右键菜单刷新页面的时候重新加载tags标签)
export default {
namespaced: true,
state: {
tagsList: [],
},
getters: {
getTagsList: (state) => {
return state.tagsList
},
},
mutations: {
SET_TAGS_LIST(state, list) {
state.tagsList = list
},
CLEAR_TAGS_LIST(state) {
state.tagsList = []
},
},
actions: {
/* 赋值tags */
updatedTags({ commit }, list = []) {
// 去掉添加的重定向路由
const arr = list.filter((o) => {
return o.path.indexOf('/redirect/') < 0
})
commit('SET_TAGS_LIST', arr)
},
/* 清除tabs信息 */
clearTags({ commit }) {
commit('CLEAR_TAGS_LIST')
},
},
}
我们来看看ulWheel跟moveToCurrentTag可能不太好理解。函数主要是是为了做什么解决什么问题。看图
ulWheel函数是为了tags太多出现滚动条的时候,鼠标滚轮可以控制滚动条左右移动
moveToCurrentTag就是切换的时候每次重新计算,计算滚动条位置,动态滚动对应位置
以上就实现页面多tab,右键菜单关闭、刷新等功能所有内容了、虽然简单但是踩了不少坑跟改了不少bug