Commit 7e8f80c0 authored by 沈翠玲's avatar 沈翠玲

tabs标签优化

parent d348955c
<template> <template>
<el-dropdown trigger="click" :teleported="false"> <ul>
<div class="more-button"> <li @click="refresh">
<i :class="'iconfont icon-xiala'"></i> <el-icon><Refresh /></el-icon>刷新
</div> </li>
<template #dropdown> <li @click="maximize">
<el-dropdown-menu> <el-icon><FullScreen /></el-icon>最大化
<el-dropdown-item @click="refresh"> </li>
<el-icon><Refresh /></el-icon>刷新 <li divided @click="closeCurrentTab" v-if="props.selectedTag.close">
</el-dropdown-item> <el-icon><Remove /></el-icon>关闭当前
<el-dropdown-item @click="maximize"> </li>
<el-icon><FullScreen /></el-icon>最大化 <li @click="closeLeftTags">
</el-dropdown-item> <el-icon><DArrowLeft /></el-icon>关闭左侧
<el-dropdown-item divided @click="closeCurrentTab"> </li>
<el-icon><Remove /></el-icon>关闭当前 <li @click="closeRightTags">
</el-dropdown-item> <el-icon><DArrowRight /></el-icon>关闭右侧
<el-dropdown-item @click="tabStore.closeTabsOnSide(route.fullPath, 'left')"> </li>
<el-icon><DArrowLeft /></el-icon>关闭左侧 <li divided @click="closeOthersTags">
</el-dropdown-item> <el-icon><CircleClose /></el-icon>关闭其它
<el-dropdown-item @click="tabStore.closeTabsOnSide(route.fullPath, 'right')"> </li>
<el-icon><DArrowRight /></el-icon>关闭右侧 <li @click="closeAllTab">
</el-dropdown-item> <el-icon><FolderDelete /></el-icon>关闭全部
<el-dropdown-item divided @click="tabStore.closeMultipleTab(route.fullPath)"> </li>
<el-icon><CircleClose /></el-icon>关闭其它 </ul>
</el-dropdown-item>
<el-dropdown-item @click="closeAllTab">
<el-icon><FolderDelete /></el-icon>关闭全部
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template> </template>
<script setup> <script setup>
import { inject, nextTick } from 'vue'; import { inject, nextTick } from 'vue';
import { HOME_URL } from '@/config'; import { HOME_URL } from '@/config';
import { useTabsStore } from '@/stores/modules/tabs'; import { useTabsStore } from '@/stores/modules/tabs';
import { useGlobalStore } from '@/stores/modules/global'; import { useGlobalStore } from '@/stores/modules/global';
import { useKeepAliveStore } from '@/stores/modules/keepAlive'; import { useKeepAliveStore } from '@/stores/modules/keepAlive';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const tabStore = useTabsStore(); const tabStore = useTabsStore();
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
const keepAliveStore = useKeepAliveStore(); const keepAliveStore = useKeepAliveStore();
const props = defineProps({
// refresh current page selectedTag: {
const refreshCurrentPage = inject('refresh'); type: [Object],
const refresh = () => { default: null,
setTimeout(() => { }
route.meta.isKeepAlive && keepAliveStore.removeKeepAliveName(route.fullPath); });
// refresh current page
const refreshCurrentPage = inject('refresh');
const refresh = () => {
router.push(props.selectedTag.path).then(res => {
route.meta.isKeepAlive && keepAliveStore.removeKeepAliveName(props.selectedTag.path);
refreshCurrentPage(false); refreshCurrentPage(false);
nextTick(() => { nextTick(() => {
route.meta.isKeepAlive && keepAliveStore.addKeepAliveName(route.fullPath); route.meta.isKeepAlive && keepAliveStore.addKeepAliveName(props.selectedTag.path);
refreshCurrentPage(true); refreshCurrentPage(true);
}); });
}, 0); })
}; };
// maximize current page // maximize current page
const maximize = () => { const maximize = () => {
router.push(props.selectedTag.path).then(res => {
globalStore.setGlobalState('maximize', true); globalStore.setGlobalState('maximize', true);
}; })
};
// Close Current const closeLeftTags = () => {
const closeCurrentTab = () => { router.push(props.selectedTag.path).then(res => {
if (route.meta.isAffix) return; tabStore.closeTabsOnSide(props.selectedTag.path, 'left')
tabStore.removeTabs(route.fullPath); })
}; }
const closeRightTags = () => {
router.push(props.selectedTag.path).then(res => {
tabStore.closeTabsOnSide(props.selectedTag.path, 'right')
})
}
const closeOthersTags = () => {
router.push(props.selectedTag.path).then(res => {
tabStore.closeMultipleTab(props.selectedTag.path)
})
}
// Close Current
const closeCurrentTab = () => {
if (!props.selectedTag.close) return;
tabStore.removeTabs(props.selectedTag.path);
};
// Close All // Close All
const closeAllTab = () => { const closeAllTab = () => {
tabStore.closeMultipleTab(); tabStore.closeMultipleTab();
router.push(HOME_URL); router.push(HOME_URL);
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@use '../index.scss'; @use '../index.scss';
</style> </style>
.tabs-box { .tabs-box {
background-color: var(--el-bg-color); background-color: var(--el-bg-color);
.tabs-menu { .tabs-menu {
position: relative;
width: 100%; width: 100%;
.el-dropdown { .el-dropdown {
position: absolute; position: absolute;
...@@ -80,3 +79,24 @@ ...@@ -80,3 +79,24 @@
} }
} }
} }
.contextmenu {
margin: 0;
background: #fff;
z-index: 3000;
position: absolute;
list-style-type: none;
padding: 5px 0;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
li {
margin: 0;
padding: 7px 16px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
\ No newline at end of file
<template> <template>
<div class="tabs-box"> <div class="tabs-box">
<div class="tabs-menu"> <div class="tabs-menu">
<el-tabs v-model="tabsMenuValue" type="card" @tab-click="tabClick" @tab-remove="tabRemove"> <el-tabs v-model="tabsMenuValue" type="card" @tab-click="tabClick" @contextmenu.prevent="openRightMenu($event)" @tab-remove="tabRemove">
<el-tab-pane <el-tab-pane
v-for="item in tabsMenuList" v-for="item in tabsMenuList"
:key="item.path" :key="item.path"
...@@ -14,7 +14,15 @@ ...@@ -14,7 +14,15 @@
</template> </template>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<MoreButton /> <!-- <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right"></i> 刷新页面</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close"></i> 关闭当前</li>
<li @click="closeOthersTags"><i class="el-icon-circle-close"></i> 关闭其他</li>
<li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back"></i> 关闭左侧</li>
<li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right"></i> 关闭右侧</li>
<li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close"></i> 全部关闭</li>
</ul> -->
<MoreButton v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu" :selectedTag="selectedTag" />
</div> </div>
</div> </div>
</template> </template>
...@@ -36,6 +44,10 @@ ...@@ -36,6 +44,10 @@
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
const tabsMenuValue = ref(route.fullPath); const tabsMenuValue = ref(route.fullPath);
const visible = ref(false);
const selectedTag = ref({})
const left = ref(0);
const top = ref(0);
const tabsMenuList = computed(() => tabStore.tabsMenuList); const tabsMenuList = computed(() => tabStore.tabsMenuList);
const tabsIcon = computed(() => globalStore.tabsIcon); const tabsIcon = computed(() => globalStore.tabsIcon);
...@@ -44,6 +56,32 @@ ...@@ -44,6 +56,32 @@
initTabs(); initTabs();
}); });
const openRightMenu = (e) => {
visible.value = false;
console.log('eee', e)
if (e.srcElement.id) {
// 右键点击的是tab
selectedTag.value = {
title: e.srcElement.innerText,
path: e.srcElement.id.replace('tab-', ''),
close: e.srcElement.firstElementChild ? true: false
}
left.value = e.clientX;
top.value = e.clientY;
visible.value = true;
}
}
watch(() => visible.value, (value)=>{
if (value) {
document.body.addEventListener('click', () => {
visible.value = false
})
} else {
document.body.removeEventListener('click', () => {
visible.value = false
})
}
})
// 监听路由的变化(防止浏览器后退/前进不变化 tabsMenuValue) // 监听路由的变化(防止浏览器后退/前进不变化 tabsMenuValue)
watch( watch(
() => route.fullPath, () => route.fullPath,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment