| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- <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-if="item.icon && tabsIcon" class="tabs-icon">
- <component :is="item.icon" />
- </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 { TabsPaneContext, TabPaneName } from "element-plus";
- import MoreButton from "./components/MoreButton.vue";
- import { HOME_URL } from "@/config";
- const route = useRoute();
- const router = useRouter();
- const tabStore = useTabsStore();
- const authStore = useAuthStore();
- const globalStore = useGlobalStore();
- const tabsMenuValue = ref(route?.fullPath || "");
- const tabsMenuList = computed(() => tabStore.tabsMenuList);
- const tabsIcon = computed(() => globalStore.tabsIcon);
- onMounted(() => {
- tabsDrop();
- initTabs();
- });
- // 监听路由的变化(防止浏览器后退/前进不变化 tabsMenuValue)
- watch(
- () => route.fullPath,
- () => {
- // 检查 route 和 route.meta 是否存在
- if (!route || !route.meta || !route.fullPath) return;
- if (route.meta.isFull) return;
- tabsMenuValue.value = route.fullPath;
- const tabsParams = {
- icon: route.meta.icon as string,
- title: route.meta.title as string,
- path: route.fullPath,
- name: route.name as string,
- close: !route.meta.isAffix,
- isKeepAlive: route.meta.isKeepAlive as boolean
- };
- tabStore.addTabs(tabsParams);
- },
- { immediate: true }
- );
- // 初始化需要固定的 tabs
- const initTabs = () => {
- authStore.flatMenuListGet.forEach(item => {
- if (item.meta.isAffix && !item.meta.isHide && !item.meta.isFull) {
- const tabsParams = {
- icon: item.meta.icon,
- title: item.meta.title,
- path: item.path,
- name: item.name,
- close: !item.meta.isAffix,
- isKeepAlive: item.meta.isKeepAlive
- };
- tabStore.addTabs(tabsParams);
- }
- });
- };
- // 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);
- }
- });
- };
- // Tab Click
- const tabClick = (tabItem: TabsPaneContext) => {
- const fullPath = tabItem.props.name as string;
- router.push(fullPath);
- };
- // Remove Tab
- const tabRemove = (fullPath: TabPaneName) => {
- // 判断是否为最后一个标签页
- if (tabStore.tabsMenuList.length === 1) {
- if (HOME_URL == fullPath) {
- return false;
- }
- tabStore.removeTabs(fullPath as string, route && route.fullPath ? fullPath == route.fullPath : false);
- router.push(HOME_URL);
- } else {
- tabStore.removeTabs(fullPath as string, route && route.fullPath ? fullPath == route.fullPath : false);
- }
- };
- </script>
- <style scoped lang="scss">
- @import "./index";
- </style>
|