2021-09-17 19:50:24 +08:00
|
|
|
import { nextTick } from 'vue';
|
2021-09-16 20:11:45 +08:00
|
|
|
import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
2021-11-20 20:14:02 +08:00
|
|
|
import type { ScrollbarInst } from 'naive-ui';
|
|
|
|
import { defineStore } from 'pinia';
|
2021-09-17 19:50:24 +08:00
|
|
|
import { router, ROUTE_HOME } from '@/router';
|
2021-11-20 21:30:49 +08:00
|
|
|
import { store, useThemeStore } from '@/store';
|
|
|
|
import { getTabRouteStorage } from '@/utils';
|
|
|
|
import type { MultiTab, MultiTabRoute } from '@/interface';
|
|
|
|
import { getHomeTabRoute, isInTabRoutes } from './helpers';
|
2021-08-13 14:22:35 +08:00
|
|
|
|
2021-09-07 17:03:59 +08:00
|
|
|
/** app状态 */
|
2021-08-13 14:22:35 +08:00
|
|
|
interface AppState {
|
2021-11-20 20:14:02 +08:00
|
|
|
layout: LayoutState;
|
2021-09-07 17:03:59 +08:00
|
|
|
menu: MenuState;
|
2021-09-16 20:11:45 +08:00
|
|
|
multiTab: MultiTab;
|
2021-09-17 19:50:24 +08:00
|
|
|
/** 重新加载标记 */
|
|
|
|
reloadFlag: boolean;
|
2021-09-01 17:43:25 +08:00
|
|
|
settingDrawer: SettingDrawer;
|
|
|
|
}
|
|
|
|
|
2021-11-20 20:14:02 +08:00
|
|
|
/** 布局状态 */
|
|
|
|
interface LayoutState {
|
|
|
|
scrollbar: ScrollbarInst | null;
|
|
|
|
}
|
|
|
|
|
2021-09-07 17:03:59 +08:00
|
|
|
/** 菜单状态 */
|
|
|
|
interface MenuState {
|
|
|
|
/** 菜单折叠 */
|
|
|
|
collapsed: boolean;
|
2021-09-27 18:41:50 +08:00
|
|
|
/** 混合菜单vertical-mix是否固定二级菜单 */
|
|
|
|
fixedMix: boolean;
|
2021-09-07 17:03:59 +08:00
|
|
|
}
|
|
|
|
|
2021-09-16 20:11:45 +08:00
|
|
|
/** 项目配置抽屉的状态 */
|
2021-09-01 17:43:25 +08:00
|
|
|
interface SettingDrawer {
|
2021-09-07 17:03:59 +08:00
|
|
|
/** 设置抽屉可见性 */
|
2021-09-01 17:43:25 +08:00
|
|
|
visible: boolean;
|
2021-08-13 14:22:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const appStore = defineStore({
|
|
|
|
id: 'app-store',
|
|
|
|
state: (): AppState => ({
|
2021-11-20 20:14:02 +08:00
|
|
|
layout: {
|
|
|
|
scrollbar: null
|
|
|
|
},
|
2021-09-07 17:03:59 +08:00
|
|
|
menu: {
|
2021-09-27 18:41:50 +08:00
|
|
|
collapsed: false,
|
|
|
|
fixedMix: false
|
2021-09-07 17:03:59 +08:00
|
|
|
},
|
2021-09-16 20:11:45 +08:00
|
|
|
multiTab: {
|
2021-09-17 19:50:24 +08:00
|
|
|
routes: [],
|
|
|
|
activeRoute: ''
|
2021-09-16 20:11:45 +08:00
|
|
|
},
|
2021-09-17 19:50:24 +08:00
|
|
|
reloadFlag: true,
|
2021-09-01 17:43:25 +08:00
|
|
|
settingDrawer: {
|
|
|
|
visible: false
|
|
|
|
}
|
2021-08-13 14:22:35 +08:00
|
|
|
}),
|
2021-09-20 02:48:53 +08:00
|
|
|
getters: {
|
|
|
|
activeMultiTabIndex(state) {
|
|
|
|
const { routes, activeRoute } = state.multiTab;
|
|
|
|
return routes.findIndex(v => v.fullPath === activeRoute);
|
|
|
|
}
|
|
|
|
},
|
2021-08-13 14:22:35 +08:00
|
|
|
actions: {
|
2021-11-20 20:14:02 +08:00
|
|
|
/** 设置scrollbar的实例 */
|
|
|
|
setScrollbarInstance(scrollbar: ScrollbarInst) {
|
|
|
|
this.layout.scrollbar = scrollbar;
|
|
|
|
},
|
2021-11-20 21:30:49 +08:00
|
|
|
/** 重置滚动条行为 */
|
2021-11-20 20:14:02 +08:00
|
|
|
resetScrollBehavior() {
|
|
|
|
const { scrollbar } = this.layout;
|
|
|
|
setTimeout(() => {
|
|
|
|
scrollbar?.scrollTo({ left: 0, top: 0 });
|
|
|
|
}, 250);
|
|
|
|
},
|
2021-09-01 17:43:25 +08:00
|
|
|
/** 折叠/展开菜单 */
|
|
|
|
handleMenuCollapse(collapsed: boolean) {
|
2021-09-07 17:03:59 +08:00
|
|
|
this.menu.collapsed = collapsed;
|
2021-09-01 17:43:25 +08:00
|
|
|
},
|
2021-09-27 18:41:50 +08:00
|
|
|
/** 设置混合菜单是否固定 */
|
|
|
|
toggleFixedMixMenu() {
|
|
|
|
this.menu.fixedMix = !this.menu.fixedMix;
|
|
|
|
},
|
2021-09-01 17:43:25 +08:00
|
|
|
/** 切换折叠/展开菜单 */
|
|
|
|
toggleMenu() {
|
2021-09-07 17:03:59 +08:00
|
|
|
this.menu.collapsed = !this.menu.collapsed;
|
2021-09-01 17:43:25 +08:00
|
|
|
},
|
2021-09-17 23:44:28 +08:00
|
|
|
/** 添加多页签的数据 */
|
2021-09-17 08:31:49 +08:00
|
|
|
addMultiTab(route: RouteLocationNormalizedLoaded) {
|
2021-09-17 19:50:24 +08:00
|
|
|
const { fullPath } = route;
|
2021-11-20 21:30:49 +08:00
|
|
|
const isExist = isInTabRoutes(this.multiTab.routes, fullPath);
|
2021-09-17 19:50:24 +08:00
|
|
|
if (!isExist) {
|
|
|
|
this.multiTab.routes.push({ ...route });
|
|
|
|
}
|
|
|
|
},
|
2021-09-17 23:44:28 +08:00
|
|
|
/** 删除多页签的数据 */
|
|
|
|
removeMultiTab(fullPath: string) {
|
2021-09-18 11:32:53 +08:00
|
|
|
const isActive = this.multiTab.activeRoute === fullPath;
|
|
|
|
const { routes } = this.multiTab;
|
|
|
|
const updateRoutes = routes.filter(v => v.fullPath !== fullPath);
|
|
|
|
this.multiTab.routes = updateRoutes;
|
|
|
|
if (isActive) {
|
|
|
|
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
|
2021-09-17 23:44:28 +08:00
|
|
|
router.push(activePath);
|
2021-09-18 11:32:53 +08:00
|
|
|
this.setActiveMultiTab(activePath);
|
2021-09-17 23:44:28 +08:00
|
|
|
}
|
|
|
|
},
|
2021-09-20 18:55:42 +08:00
|
|
|
/**
|
|
|
|
* 删除所有多页签只保留路由首页
|
|
|
|
* @param exclude - 保留的多页签
|
|
|
|
*/
|
|
|
|
clearMultiTab(exclude: string[] = []) {
|
|
|
|
const remain = [ROUTE_HOME.path, ...exclude];
|
|
|
|
const { routes } = this.multiTab;
|
|
|
|
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
|
|
|
|
this.multiTab.routes = updateRoutes;
|
|
|
|
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
|
|
|
|
router.push(activePath);
|
|
|
|
this.setActiveMultiTab(activePath);
|
|
|
|
},
|
2021-11-08 19:33:38 +08:00
|
|
|
/** 删除左边多页签 */
|
|
|
|
clearLeftMultiTab(fullPath: string) {
|
|
|
|
const { routes } = this.multiTab;
|
|
|
|
const currentIndex = routes.findIndex(route => route.fullPath === fullPath);
|
|
|
|
const activeIndex = this.activeMultiTabIndex;
|
|
|
|
if (currentIndex > -1) {
|
|
|
|
const remain = [ROUTE_HOME.path, ...routes.slice(currentIndex).map(v => v.fullPath)];
|
|
|
|
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
|
|
|
|
this.multiTab.routes = updateRoutes;
|
|
|
|
if (activeIndex < currentIndex) {
|
|
|
|
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
|
|
|
|
router.push(activePath);
|
|
|
|
this.setActiveMultiTab(activePath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/** 删除右边多页签 */
|
|
|
|
clearRightMultiTab(fullPath: string) {
|
|
|
|
const { routes } = this.multiTab;
|
|
|
|
const currentIndex = routes.findIndex(route => route.fullPath === fullPath);
|
|
|
|
const activeIndex = this.activeMultiTabIndex;
|
|
|
|
if (currentIndex > -1) {
|
|
|
|
const remain = [ROUTE_HOME.path, ...routes.slice(0, currentIndex + 1).map(v => v.fullPath)];
|
|
|
|
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
|
|
|
|
this.multiTab.routes = updateRoutes;
|
|
|
|
if (activeIndex > currentIndex) {
|
|
|
|
router.push(fullPath);
|
|
|
|
this.setActiveMultiTab(fullPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2021-09-17 23:44:28 +08:00
|
|
|
/** 点击单个页签tab */
|
2021-09-17 19:50:24 +08:00
|
|
|
handleClickTab(fullPath: string) {
|
|
|
|
if (this.multiTab.activeRoute !== fullPath) {
|
|
|
|
router.push(fullPath);
|
|
|
|
this.setActiveMultiTab(fullPath);
|
|
|
|
}
|
|
|
|
},
|
2021-09-17 23:44:28 +08:00
|
|
|
/** 设置当前路由对应的页签为激活状态 */
|
2021-09-17 19:50:24 +08:00
|
|
|
setActiveMultiTab(fullPath: string) {
|
|
|
|
this.multiTab.activeRoute = fullPath;
|
|
|
|
},
|
|
|
|
/** 初始化多页签数据 */
|
|
|
|
initMultiTab() {
|
2021-11-20 21:30:49 +08:00
|
|
|
const theme = useThemeStore();
|
2021-09-17 19:50:24 +08:00
|
|
|
const { currentRoute } = router;
|
|
|
|
const isHome = currentRoute.value.name === ROUTE_HOME.name;
|
2021-11-20 21:30:49 +08:00
|
|
|
const home = getHomeTabRoute(currentRoute.value);
|
|
|
|
const routes: MultiTabRoute[] = theme.multiTabStyle.isCache ? getTabRouteStorage() : [];
|
|
|
|
const hasHome = isInTabRoutes(routes, home.fullPath);
|
|
|
|
const hasCurrent = isInTabRoutes(routes, currentRoute.value.fullPath);
|
|
|
|
if (!hasHome) {
|
|
|
|
routes.unshift(home);
|
|
|
|
}
|
|
|
|
if (!isHome && !hasCurrent) {
|
2021-09-17 19:50:24 +08:00
|
|
|
routes.push(currentRoute.value);
|
|
|
|
}
|
|
|
|
this.multiTab.routes = routes;
|
|
|
|
this.setActiveMultiTab(currentRoute.value.fullPath);
|
|
|
|
},
|
|
|
|
/** 重新加载页面 */
|
2021-09-18 22:16:31 +08:00
|
|
|
handleReload() {
|
2021-09-17 19:50:24 +08:00
|
|
|
this.reloadFlag = false;
|
2021-09-18 22:16:31 +08:00
|
|
|
nextTick(() => {
|
|
|
|
this.reloadFlag = true;
|
2021-11-20 20:14:02 +08:00
|
|
|
this.resetScrollBehavior();
|
2021-09-18 22:16:31 +08:00
|
|
|
});
|
2021-09-17 08:31:49 +08:00
|
|
|
},
|
2021-09-01 17:43:25 +08:00
|
|
|
/** 打开配置抽屉 */
|
|
|
|
openSettingDrawer() {
|
|
|
|
this.settingDrawer.visible = true;
|
2021-08-13 14:22:35 +08:00
|
|
|
},
|
2021-09-01 17:43:25 +08:00
|
|
|
/** 关闭配置抽屉 */
|
|
|
|
closeSettingDrawer() {
|
|
|
|
this.settingDrawer.visible = false;
|
2021-08-13 14:22:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
export default function useAppStore() {
|
|
|
|
return appStore(store);
|
|
|
|
}
|