import { defineComponent, computed, nextTick, onMounted, watch, onBeforeUnmount } from 'vue'; import { storeToRefs } from 'pinia'; import { useRoute, useRouter } from 'vue-router'; import { usePermissionStore, useSettingStore, useTabsRouterStore } from '@/store'; import LayoutHeader from './components/Header.vue'; import LayoutBreadcrumb from './components/Breadcrumb.vue'; import LayoutFooter from './components/Footer.vue'; import LayoutSideNav from './components/SideNav'; import LayoutContent from './components/Content.vue'; import Setting from './setting.vue'; import { prefix } from '@/config/global'; import { TRouterInfo } from '@/interface'; import '@/style/layout.less'; const name = `${prefix}-base-layout`; export default defineComponent({ name, setup() { const route = useRoute(); const router = useRouter(); const permissionStore = usePermissionStore(); const settingStore = useSettingStore(); const tabsRouterStore = useTabsRouterStore(); const { routers: menuRouters } = storeToRefs(permissionStore); const setting = storeToRefs(settingStore); const mainLayoutCls = computed(() => [ { 't-layout--with-sider': settingStore.showSidebar, }, ]); const headerMenu = computed(() => { if (settingStore.layout === 'mix') { if (settingStore.splitMenu) { return menuRouters.value.map((menu) => ({ ...menu, children: [], })); } return []; } return menuRouters.value; }); const sideMenu = computed(() => { const { layout, splitMenu } = settingStore; let newMenuRouters = menuRouters.value; if (layout === 'mix' && splitMenu) { newMenuRouters.forEach((menu) => { if (route.path.indexOf(menu.path) === 0) { newMenuRouters = menu.children.map((subMenu) => ({ ...subMenu, path: `${menu.path}/${subMenu.path}` })); } }); } return newMenuRouters; }); const appendNewRoute = () => { const { path, meta: { title }, name, } = route; tabsRouterStore.appendTabRouterList({ path, title: title as string, name, isAlive: true }); }; const getTabRouterListCache = () => { tabsRouterStore.initTabRouterList(JSON.parse(localStorage.getItem('tabRouterList'))); }; const setTabRouterListCache = () => { const { tabRouters } = tabsRouterStore; localStorage.setItem('tabRouterList', JSON.stringify(tabRouters)); }; onMounted(() => { appendNewRoute(); }); // 如果不需要持久化标签页可以注释掉以下的 onMounted 和 onBeforeUnmount 的内容 onMounted(() => { if (localStorage.getItem('tabRouterList')) getTabRouterListCache(); window.addEventListener('beforeunload', setTabRouterListCache); }); onBeforeUnmount(() => { window.removeEventListener('beforeunload', setTabRouterListCache); }); watch( () => route.path, () => { appendNewRoute(); }, ); const handleRemove = ({ value: path, index }) => { const { tabRouters } = tabsRouterStore; const nextRouter = tabRouters[index + 1] || tabRouters[index - 1]; tabsRouterStore.subtractCurrentTabRouter({ path, routeIdx: index }); if (path === route.path) { router.push(nextRouter.path); } }; const handleChangeCurrentTab = (path: string) => { router.push(path); }; const handleRefresh = (currentPath: string, routeIdx: number) => { tabsRouterStore.toggleTabRouterAlive(routeIdx); nextTick(() => { tabsRouterStore.toggleTabRouterAlive(routeIdx); router.replace({ path: currentPath }); }); }; const handleCloseAhead = (path: string, routeIdx: number) => { tabsRouterStore.subtractTabRouterAhead({ path, routeIdx }); }; const handleCloseBehind = (path: string, routeIdx: number) => { tabsRouterStore.subtractTabRouterBehind({ path, routeIdx }); }; const handleCloseOther = (path: string, routeIdx: number) => { tabsRouterStore.subtractTabRouterOther({ path, routeIdx }); }; const renderSidebar = () => { return ( settingStore.showSidebar && ( ) ); }; const renderHeader = () => { return ( settingStore.showHeader && ( ) ); }; const renderFooter = () => { return ( ); }; const renderContent = () => { const { showBreadcrumb, showFooter, isUseTabsRouter } = settingStore; const { tabRouters } = tabsRouterStore; return ( {isUseTabsRouter && ( {tabRouters.map((router: TRouterInfo, idx: number) => ( router.path === route.path ? ( handleRefresh(router.path, idx)}> 刷新 {idx > 1 && ( handleCloseAhead(router.path, idx)}> 关闭左侧 )} {idx < tabRouters.length - 1 && ( handleCloseBehind(router.path, idx)}> 关闭右侧 )} handleCloseOther(router.path, idx)}> 关闭其它 ) : null, }} > {!router.isHome ? router.title : } } removable={!router.isHome} /> ))} )} {showBreadcrumb && } {showFooter && renderFooter()} ); }; return { setting, mainLayoutCls, renderSidebar, renderHeader, renderContent, }; }, render() { const { layout } = this.setting; const header = this.renderHeader(); const sidebar = this.renderSidebar(); const content = this.renderContent(); return (
{layout === 'side' ? ( {sidebar} {[header, content]} ) : ( {header} {[sidebar, content]} )}
); }, });