mirror of
https://gitee.com/chu1204505056/vue-admin-beautiful.git
synced 2025-10-09 10:44:19 +08:00
✨tabsBar支持关闭其他、关闭左侧、关闭右侧、关闭全部
This commit is contained in:
parent
80b8eb589d
commit
239e1e7d7d
@ -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>
|
||||||
|
@ -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 格式化时间
|
||||||
|
Loading…
x
Reference in New Issue
Block a user