123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- <template>
- <div class="tabs-box flx-center">
- <div class="flx-shrink pl-12 pr-8" style="cursor: pointer" @click="gohome">
- <i class="tabs-icon iconfont iconhome-smile"></i>
- </div>
- <el-divider direction="vertical"></el-divider>
- <div class="tabs-menu flx-1">
- <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>
- <template v-if="item.path.indexOf('/detail') > -1 || item.path.indexOf('/edit?') > -1">
- <div class="flx-start">
- <i
- class="iconfont flx-shrink tabs-icon"
- v-show="item.icon && tabsIcon"
- :class="item.path.indexOf('/edit?') > -1 ? 'iconedit-02' : item.icon"
- ></i>
- <div class="title flx-1 flx-col">
- <template v-if="getParam(item.path, 'code')">
- {{ getParam(item.path, "code") }}
- <span class="text-f-s">
- {{ $t(`menu.${item.name}`) }}
- </span>
- </template>
- <template v-else>
- {{ $t(`menu.${item.name}`) }}
- </template>
- </div>
- </div>
- </template>
- <template v-else>
- <i
- class="iconfont flx-shrink tabs-icon"
- v-show="item.icon && tabsIcon"
- :class="item.path.indexOf('/new') > -1 ? 'iconPlus_light' : item.icon"
- ></i>
- {{ $t(`menu.${item.name}`) }}
- </template>
- </template>
- </el-tab-pane>
- </el-tabs>
- <MoreButton v-if="showMoreButton" />
- </div>
- <slot name="menu-right" />
- </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);
- const tabsIcon = computed(() => globalStore.tabsIcon);
- onMounted(() => {
- tabsDrop();
- initTabs();
- });
- const props = defineProps({
- showMoreButton: {
- type: Boolean,
- default: true
- }
- });
- // 监听路由的变化(防止浏览器后退/前进不变化 tabsMenuValue)
- watch(
- () => route.fullPath,
- () => {
- if (route.meta.isFull) return;
- console.log("watch route :>> ", route);
- 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
- };
- console.log("tabStore :>> ", tabStore, route);
- let isReplace = false;
- if (tabsParams.path.indexOf("/edit?") > -1 || tabsParams.path.indexOf("/edit/") > -1) {
- let key = "/edit?";
- let name = "";
- let _path = tabsParams.path.replace(key, "/detail?");
- // 使用路由参数的地址,忽略查询参数后,查找相同地址
- let _path2 = tabsParams.path.replace("/edit/", "/detail/");
- let tabsMenuList = tabStore.tabsMenuList;
- for (let i = 0; i < tabsMenuList.length; i++) {
- if (tabsMenuList[i].path == _path || tabsMenuList[i].path.split("?")[0] == _path2.split("?")[0]) {
- name = tabsMenuList[i].name;
- tabsMenuList[i] = tabsParams;
- isReplace = true;
- break;
- }
- }
- console.log("keilll name :>> ", name);
- tabStore.setTabs(tabsMenuList);
- name && keepAliveStore.removeKeepAliveName(route);
- } else if (tabsParams.path.indexOf("/detail?") > -1 || tabsParams.path.indexOf("/detail/") > -1) {
- let key = "/detail?";
- let _path = tabsParams.path.replace(key, "/edit?");
- // 使用路由参数的地址,忽略查询参数后,查找相同地址
- let _path2 = tabsParams.path.replace("/detail/", "/edit/");
- let tabsMenuList = tabStore.tabsMenuList;
- for (let i = 0; i < tabsMenuList.length; i++) {
- if (tabsMenuList[i].path == _path || tabsMenuList[i].path.split("?")[0] == _path2.split("?")[0]) {
- tabsMenuList[i] = tabsParams;
- isReplace = true;
- break;
- }
- }
- tabStore.setTabs(tabsMenuList);
- route.meta.isKeepAlive && keepAliveStore.addKeepAliveName(route);
- console.log("add keepAliveStore.keepAliveName :>> ", keepAliveStore.keepAliveName);
- }
- !isReplace && tabStore.addTabs(tabsParams);
- !isReplace && route.meta.isKeepAlive && keepAliveStore.addKeepAliveName(route);
- },
- { 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.meta.isHide && !item.meta.isFull) {
- const tabsParams: any = {
- 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) => {
- // const name = tabStore.tabsMenuList.filter(item => item.path == fullPath)[0].name || "";
- let routeItem = tabStore.tabsMenuList.filter(item => item.path == fullPath)[0];
- console.log("tabRemove tabStore.tabsMenuList :>> ", tabStore.tabsMenuList);
- console.log("tabRemove routeItem :>> ", routeItem);
- keepAliveStore.removeKeepAliveName(routeItem);
- let arr = keepAliveStore.getKeepAliveList;
- arr = arr.filter(item => item.fullPath !== routeItem.path);
- console.log("tabRemove arr :>> ", arr);
- keepAliveStore.setKeepAliveList(arr);
- tabStore.removeTabs(fullPath as string, fullPath == route.fullPath);
- };
- // get Path param
- const getParam = (path: string, name: string) => {
- let reg = new RegExp(name + "=(.*?)(&|$)");
- let res = path.match(reg);
- return res ? res[1] : null;
- };
- const gohome = () => {
- router.push("/home/index");
- };
- defineExpose({
- tabRemove
- });
- </script>
- <style scoped lang="scss">
- @import "./index.scss";
- </style>
|