|
@@ -1,20 +1,26 @@
|
|
|
<template>
|
|
|
- <div class="tabs">
|
|
|
- <el-scrollbar ref="scrollbarDom">
|
|
|
- <div style="display: flex; flex-wrap: nowrap">
|
|
|
- <Item v-for="menu in menuList" :key="menu.meta.title" :active="activeMenu === menu.path" :menu="menu" @close="delMenu(menu)" />
|
|
|
+ <div class="tabs-box">
|
|
|
+ <el-scrollbar ref="scrollbarDom" class="tab">
|
|
|
+ <div class="scrollbar-flex-content">
|
|
|
+ <Item v-for="menu in menuList" :key="menu.meta.title" :active="activeMenu === menu.path" :menu="menu"
|
|
|
+ @close="delMenu(menu)"/>
|
|
|
</div>
|
|
|
</el-scrollbar>
|
|
|
<div class="handle">
|
|
|
<el-dropdown placement="bottom">
|
|
|
<div class="el-dropdown-link">
|
|
|
- <el-icon><ArrowDown /></el-icon>
|
|
|
+ <el-icon>
|
|
|
+ <ArrowDown/>
|
|
|
+ </el-icon>
|
|
|
</div>
|
|
|
<template #dropdown>
|
|
|
<el-dropdown-menu>
|
|
|
- <el-dropdown-item :disabled="currentDisabled" icon="CircleClose" @click="closeCurrentRoute"> 关闭当前标签 </el-dropdown-item>
|
|
|
- <el-dropdown-item :disabled="menuList.length < 3" icon="CircleClose" @click="closeOtherRoute"> 关闭其他标签 </el-dropdown-item>
|
|
|
- <el-dropdown-item :disabled="menuList.length <= 1" icon="CircleClose" @click="closeAllRoute"> 关闭所有标签 </el-dropdown-item>
|
|
|
+ <el-dropdown-item :disabled="currentDisabled" icon="CircleClose" @click="closeCurrentRoute"> 关闭当前标签
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item :disabled="menuList.length < 3" icon="CircleClose" @click="closeOtherRoute"> 关闭其他标签
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item :disabled="menuList.length <= 1" icon="CircleClose" @click="closeAllRoute"> 关闭所有标签
|
|
|
+ </el-dropdown-item>
|
|
|
</el-dropdown-menu>
|
|
|
</template>
|
|
|
</el-dropdown>
|
|
@@ -24,10 +30,11 @@
|
|
|
|
|
|
<script name="tabs" setup>
|
|
|
import Item from './item.vue'
|
|
|
-import { computed, nextTick, ref, watch } from 'vue'
|
|
|
-import { useStore } from 'vuex'
|
|
|
-import { useRoute, useRouter } from 'vue-router'
|
|
|
+import {computed, nextTick, ref, watch} from 'vue'
|
|
|
+import {useStore} from 'vuex'
|
|
|
+import {useRoute, useRouter} from 'vue-router'
|
|
|
import tabsHook from './tabsHook'
|
|
|
+import {getScrollTop} from "@/utils/el-table-scroll";
|
|
|
|
|
|
const store = useStore()
|
|
|
const route = useRoute()
|
|
@@ -35,7 +42,7 @@ const router = useRouter()
|
|
|
const scrollbarDom = ref(null)
|
|
|
const defaultMenu = {
|
|
|
path: '/dashboard',
|
|
|
- meta: { title: '首页', hideClose: true },
|
|
|
+ meta: {title: '首页', hideClose: true},
|
|
|
}
|
|
|
const currentDisabled = computed(() => route.path === defaultMenu.path)
|
|
|
|
|
@@ -81,7 +88,7 @@ function closeAllRoute() {
|
|
|
|
|
|
// 添加新的菜单项
|
|
|
function addMenu(menu) {
|
|
|
- let { path, meta, name } = menu
|
|
|
+ let {path, meta, name} = menu
|
|
|
if (meta.activeMenu) {
|
|
|
let a = menuList.value.some((obj) => {
|
|
|
return obj.path === meta.activeMenu
|
|
@@ -89,7 +96,7 @@ function addMenu(menu) {
|
|
|
if (!a) {
|
|
|
menuList.value.push({
|
|
|
path: meta.activeMenu,
|
|
|
- meta: { title: meta.parentName },
|
|
|
+ meta: {title: meta.parentName},
|
|
|
})
|
|
|
}
|
|
|
return
|
|
@@ -115,8 +122,8 @@ function delMenu(menu) {
|
|
|
store.commit('keepAlive/delKeepAliveComponentsName', menu.name)
|
|
|
}
|
|
|
menuList.value.splice(
|
|
|
- menuList.value.findIndex((item) => item.path === menu.path),
|
|
|
- 1
|
|
|
+ menuList.value.findIndex((item) => item.path === menu.path),
|
|
|
+ 1
|
|
|
)
|
|
|
}
|
|
|
if (menu.path === activeMenu.value) {
|
|
@@ -134,7 +141,9 @@ function initMenu(menu) {
|
|
|
nextTick(() => {
|
|
|
try {
|
|
|
setPosition()
|
|
|
- } catch (e) {}
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e)
|
|
|
+ }
|
|
|
})
|
|
|
}
|
|
|
|
|
@@ -142,12 +151,12 @@ function initMenu(menu) {
|
|
|
function setPosition() {
|
|
|
if (scrollbarDom.value) {
|
|
|
const domBox = {
|
|
|
- scrollbar: scrollbarDom.value.scrollbar.querySelector('.el-scrollbar__wrap '),
|
|
|
- activeDom: scrollbarDom.value.scrollbar.querySelector('.active'),
|
|
|
- activeFather: scrollbarDom.value.scrollbar.querySelector('.el-scrollbar__view'),
|
|
|
+ scrollbar: scrollbarDom.value.$el.querySelector('.el-scrollbar__wrap '),
|
|
|
+ activeDom: scrollbarDom.value.$el.querySelector('.active'),
|
|
|
+ activeFather: scrollbarDom.value.$el.querySelector('.el-scrollbar__view'),
|
|
|
}
|
|
|
- for (let i in domBox) {
|
|
|
- if (!domBox[i]) {
|
|
|
+ for (let key in domBox) {
|
|
|
+ if (!domBox[key]) {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
@@ -156,12 +165,15 @@ function setPosition() {
|
|
|
activeDom: domBox.activeDom.getBoundingClientRect(),
|
|
|
activeFather: domBox.activeFather.getBoundingClientRect(),
|
|
|
}
|
|
|
- const num = domData.activeDom.x - domData.activeFather.x + (1 / 2) * domData.activeDom.width - (1 / 2) * domData.scrollbar.width
|
|
|
- domBox.scrollbar.scrollLeft = num
|
|
|
+ scrollbarDom.value.scrollTo({
|
|
|
+ top: 0,
|
|
|
+ left: domData.activeDom.x - domData.activeFather.x + (1 / 2) * domData.activeDom.width - (1 / 2) * domData.scrollbar.width,
|
|
|
+ behavior: 'smooth',
|
|
|
+ })
|
|
|
+ // domBox.scrollbar.scrollLeft = domData.activeDom.x - domData.activeFather.x + (1 / 2) * domData.activeDom.width - (1 / 2) * domData.scrollbar.width
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 配置需要缓存的数据
|
|
|
function setKeepAliveData() {
|
|
|
let keepAliveNames = []
|
|
|
menuList.value.forEach((menu) => {
|
|
@@ -170,13 +182,12 @@ function setKeepAliveData() {
|
|
|
store.commit('keepAlive/setKeepAliveComponentsName', keepAliveNames)
|
|
|
}
|
|
|
|
|
|
-// 初始化时调用:1. 新增菜单 2. 初始化activeMenu
|
|
|
addMenu(route)
|
|
|
initMenu(route)
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.tabs {
|
|
|
+.tabs-box {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
@@ -186,10 +197,14 @@ initMenu(route)
|
|
|
border-top: 1px solid var(--system-header-border-color);
|
|
|
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
+ .tab {
|
|
|
+ width: calc(100% - 40px);
|
|
|
+ }
|
|
|
+
|
|
|
.handle {
|
|
|
min-width: 35px;
|
|
|
height: 100%;
|
|
|
- background-color: rgb(228, 228, 228);
|
|
|
+ background-color: rgb(234, 233, 233);
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
@@ -215,13 +230,15 @@ initMenu(route)
|
|
|
overflow: hidden;
|
|
|
width: 100%;
|
|
|
}
|
|
|
+
|
|
|
:deep(.scroll-container .el-scrollbar__bar) {
|
|
|
- bottom: 0px;
|
|
|
+ bottom: 0;
|
|
|
}
|
|
|
|
|
|
:deep(.scroll-container .el-scrollbar__wrap) {
|
|
|
height: 49px;
|
|
|
}
|
|
|
+
|
|
|
.tags-view-container {
|
|
|
height: 34px;
|
|
|
flex: 1;
|
|
@@ -240,4 +257,11 @@ initMenu(route)
|
|
|
outline: none;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+.scrollbar-flex-content {
|
|
|
+ display: flex;
|
|
|
+ width: calc(100% - 50px);
|
|
|
+ //overflow-x: scroll;
|
|
|
+}
|
|
|
</style>
|