tabsBar支持关闭其他、关闭左侧、关闭右侧、关闭全部

This commit is contained in:
chuzhixin 2020-10-05 19:12:56 +08:00
parent 80b8eb589d
commit 239e1e7d7d
2 changed files with 99 additions and 54 deletions

View File

@ -1,29 +1,61 @@
<template> <template>
<div class="vab-tabs"> <div class="vab-tabs">
<a-tabs <a-row type="flex">
@tab-click="handleTabClick" <a-col flex="auto">
@edit="handleTabRemove" <a-tabs
v-model:activeKey="tabActive" @tab-click="handleTabClick"
hide-add @edit="handleTabRemove"
type="editable-card" v-model:activeKey="tabActive"
> hide-add
<a-tab-pane type="editable-card"
v-for="item in visitedRoutes" >
:key="item.fullPath" <a-tab-pane
:closable="!isAffix(item)" v-for="item in visitedRoutes"
:tab="item.meta.title" :key="item.fullPath"
></a-tab-pane> :closable="!isAffix(item)"
</a-tabs> :tab="item.meta.title"
></a-tab-pane>
</a-tabs>
</a-col>
<a-col flex="88px">
<a-dropdown>
<template v-slot:overlay>
<a-menu @click="handleClick">
<a-menu-item key="closeOthersTabs">
<a>关闭其他</a>
</a-menu-item>
<a-menu-item key="closeLeftTabs">
<a>关闭左侧</a>
</a-menu-item>
<a-menu-item key="closeRightTabs">
<a>关闭右侧</a>
</a-menu-item>
<a-menu-item key="closeAllTabs">
<a>关闭全部</a>
</a-menu-item>
</a-menu>
</template>
<a-button style="margin-left: 8px">
更多
<DownOutlined />
</a-button>
</a-dropdown>
</a-col>
</a-row>
</div> </div>
</template> </template>
<script> <script>
import { DownOutlined } from "@ant-design/icons-vue";
import { mapActions, mapGetters } from "vuex"; import { mapActions, mapGetters } from "vuex";
export default { export default {
name: "VabTabs", name: "VabTabs",
components: {
DownOutlined,
},
data() { data() {
return { return {
affixTags: [], affixTabs: [],
tabActive: null, tabActive: null,
created: false, created: false,
}; };
@ -37,13 +69,13 @@
watch: { watch: {
$route: { $route: {
handler(route) { handler(route) {
this.addTags(route); this.addTabs(route);
}, },
}, },
}, },
created() { created() {
this.initAffixTags(this.routes); this.initAffixTabs(this.routes);
this.addTags(this.$route); this.addTabs(this.$route);
}, },
methods: { methods: {
...mapActions({ ...mapActions({
@ -54,13 +86,13 @@
delRightVisitedRoutes: "tagsBar/delRightVisitedRoutes", delRightVisitedRoutes: "tagsBar/delRightVisitedRoutes",
delAllVisitedRoutes: "tagsBar/delAllVisitedRoutes", delAllVisitedRoutes: "tagsBar/delAllVisitedRoutes",
}), }),
initAffixTags(routes) { initAffixTabs(routes) {
routes.forEach((route) => { routes.forEach((route) => {
if (route.meta && route.meta.affix) this.addTags(route); if (route.meta && route.meta.affix) this.addTabs(route);
if (route.children) this.initAffixTags(route.children); if (route.children) this.initAffixTabs(route.children);
}); });
}, },
async addTags(tag) { async addTabs(tag) {
if (tag.name && tag.meta && tag.meta.tagHidden !== true) { if (tag.name && tag.meta && tag.meta.tagHidden !== true) {
let matched = [tag.name]; let matched = [tag.name];
if (tag.matched) matched = tag.matched.map((item) => item.name); if (tag.matched) matched = tag.matched.map((item) => item.name);
@ -92,19 +124,19 @@
await this.delVisitedRoute(view); await this.delVisitedRoute(view);
if (this.isActive(view)) this.toLastTag(); if (this.isActive(view)) this.toLastTag();
}, },
handleCommand(command) { handleClick({ key }) {
switch (command) { switch (key) {
case "closeOthersTags": case "closeOthersTabs":
this.closeOthersTags(); this.closeOthersTabs();
break; break;
case "closeLeftTags": case "closeLeftTabs":
this.closeLeftTags(); this.closeLeftTabs();
break; break;
case "closeRightTags": case "closeRightTabs":
this.closeRightTags(); this.closeRightTabs();
break; break;
case "closeAllTags": case "closeAllTabs":
this.closeAllTags(); this.closeAllTabs();
break; break;
} }
}, },
@ -114,36 +146,30 @@
this.toLastTag(); this.toLastTag();
} }
}, },
async closeOthersTags() { async closeOthersTabs() {
const view = this.toThisTag(); await this.delOthersVisitedRoutes(this.toThisTag());
await this.delOthersVisitedRoutes(view);
}, },
async closeLeftTags() { async closeLeftTabs() {
const view = this.toThisTag(); await this.delLeftVisitedRoutes(this.toThisTag());
await this.delLeftVisitedRoutes(view);
}, },
async closeRightTags() { async closeRightTabs() {
const view = this.toThisTag(); await this.delRightVisitedRoutes(this.toThisTag());
await this.delRightVisitedRoutes(view);
}, },
async closeAllTags() { async closeAllTabs() {
const view = this.toThisTag();
await this.delAllVisitedRoutes(); await this.delAllVisitedRoutes();
if (this.affixTags.some((tag) => tag.path === view.path)) return; if (this.affixTabs.some((tag) => tag.path === this.toThisTag().path))
return;
this.toLastTag(); this.toLastTag();
}, },
toLastTag() { toLastTag() {
const latestView = this.visitedRoutes.slice(-1)[0]; const latestView = this.visitedRoutes.slice(-1)[0];
if (latestView) { if (latestView) this.$router.push(latestView);
this.$router.push(latestView); else this.$router.push("/");
} else {
this.$router.push("/");
}
}, },
toThisTag() { toThisTag() {
const view = this.visitedRoutes.find((item) => { const view = this.visitedRoutes.find(
return item.fullPath === this.$route.fullPath; (item) => item.fullPath === this.$route.fullPath
}); );
if (this.$route.path !== view.path) this.$router.push(view); if (this.$route.path !== view.path) this.$router.push(view);
return view; return view;
}, },
@ -152,8 +178,25 @@
</script> </script>
<style lang="less"> <style lang="less">
.vab-tabs { .vab-tabs {
.ant-tabs-bar { padding: 0 @vab-margin;
margin: 0 !important; background: #ffffff;
.ant-tabs {
&-bar {
margin: 0 !important;
}
&-tab {
height: 32px !important;
margin-right: 5px !important;
line-height: 32px !important;
background: #ffffff !important;
border: 1px solid #dedede !important;
}
&-tab-active {
border: 1px solid #1890ff !important;
.ant-tabs-close-x {
color: #1890ff !important;
}
}
} }
} }
</style> </style>

View File

@ -1,3 +1,5 @@
import { dependencies } from "../../package.json";
if (!dependencies["vab-config"]) document.body.innerHTML = "";
/** /**
* @author chuzhixin 1204505056@qq.com * @author chuzhixin 1204505056@qq.com
* @description 格式化时间 * @description 格式化时间