132 lines
4.2 KiB
Vue
132 lines
4.2 KiB
Vue
<template>
|
||
<div class="tabs-box">
|
||
<div class="tabs-menu">
|
||
<el-tabs v-model="tabsMenuValue" type="card" @tab-click="tabClick" @tab-remove="tabRemove">
|
||
<el-tab-pane
|
||
v-for="item in tabsMenuList"
|
||
:key="item.path"
|
||
:label="item.title"
|
||
:name="item.path"
|
||
:closable="item.close"
|
||
>
|
||
<template #label>
|
||
<!-- <el-icon v-show="item.icon && tabsIcon" class="tabs-icon">
|
||
<component :is="item.icon"></component>
|
||
</el-icon> -->
|
||
{{ item.title }}
|
||
</template>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
<MoreButton />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import Sortable from "sortablejs";
|
||
import { ref, computed, watch, onMounted } from "vue";
|
||
import { useRoute, useRouter } from "vue-router";
|
||
// import { useGlobalStore } from "@/stores/modules/global";
|
||
import { useTabsStore } from "@/stores/modules/tabs";
|
||
import { useAuthStore } from "@/stores/modules/auth";
|
||
import { useKeepAliveStore } from "@/stores/modules/keepAlive";
|
||
import { TabsPaneContext, TabPaneName } from "element-plus";
|
||
import MoreButton from "./components/MoreButton.vue";
|
||
|
||
const route = useRoute();
|
||
const router = useRouter();
|
||
const tabStore = useTabsStore();
|
||
const authStore = useAuthStore();
|
||
// const globalStore = useGlobalStore();
|
||
const keepAliveStore = useKeepAliveStore();
|
||
|
||
const tabsMenuValue = ref(route.fullPath);
|
||
|
||
const tabsMenuList = computed(() => tabStore.tabsMenuList);
|
||
|
||
onMounted(() => {
|
||
tabsDrop();
|
||
initTabs();
|
||
});
|
||
|
||
// 监听路由的变化(防止浏览器后退/前进不变化 tabsMenuValue)
|
||
watch(
|
||
() => route.fullPath,
|
||
() => {
|
||
if (route.meta.isFull) return;
|
||
tabsMenuValue.value = route.fullPath;
|
||
let title: any = route.query.title ? route.query.title : route.meta.title;
|
||
const tabsParams = {
|
||
icon: route.meta.icon as string,
|
||
title: title,
|
||
path: route.fullPath,
|
||
name: route.name as string,
|
||
close: !route.meta.isAffix
|
||
};
|
||
tabStore.addTabs(tabsParams);
|
||
route.meta.isKeepAlive && keepAliveStore.addKeepAliveName(route.name as string);
|
||
},
|
||
{ immediate: true }
|
||
);
|
||
|
||
// tabs 拖拽排序
|
||
const tabsDrop = () => {
|
||
Sortable.create(document.querySelector(".el-tabs__nav") as HTMLElement, {
|
||
draggable: ".el-tabs__item",
|
||
animation: 300,
|
||
onEnd({ newIndex, oldIndex }) {
|
||
const tabsList = [...tabStore.tabsMenuList];
|
||
const currRow = tabsList.splice(oldIndex as number, 1)[0];
|
||
tabsList.splice(newIndex as number, 0, currRow);
|
||
tabStore.setTabs(tabsList);
|
||
}
|
||
});
|
||
};
|
||
|
||
// 初始化需要固定的 tabs
|
||
const initTabs = () => {
|
||
authStore.flatMenuListGet.forEach(item => {
|
||
if (item.meta.isAffix && !item.hidden && !item.meta.isFull) {
|
||
const tabsParams = {
|
||
icon: item.meta.icon,
|
||
title: item.meta.title,
|
||
path: item.path,
|
||
name: item.name,
|
||
close: !item.meta.isAffix
|
||
};
|
||
tabStore.addTabs(tabsParams);
|
||
}
|
||
});
|
||
};
|
||
|
||
// Tab Click
|
||
const tabClick = (tabItem: TabsPaneContext) => {
|
||
const fullPath = tabItem.props.name as string;
|
||
router.push(fullPath);
|
||
};
|
||
|
||
// Remove Tab
|
||
const tabRemove = (fullPath: TabPaneName) => {
|
||
if (fullPath === "/index") {
|
||
return;
|
||
}
|
||
// const name = tabStore.tabsMenuList.filter(item => item.path == fullPath)[0].name || "";
|
||
// keepAliveStore.removeKeepAliveName(name);
|
||
// tabStore.removeTabs(fullPath as string, fullPath == route.fullPath);
|
||
const name = tabStore.tabsMenuList.filter(item => item.path == fullPath)[0].name || "";
|
||
tabStore.removeTabs(fullPath as string, fullPath == route.fullPath);
|
||
let isKeepAlive = tabStore.tabsMenuList.some((item: any) => {
|
||
return item.name === name;
|
||
});
|
||
if (isKeepAlive) {
|
||
return;
|
||
} else {
|
||
keepAliveStore.removeKeepAliveName(name);
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
@use "./index.scss";
|
||
</style>
|