mirror of
				https://github.com/soybeanjs/soybean-admin.git
				synced 2025-11-04 15:53:43 +08:00 
			
		
		
		
	feat(projects): 多页签绑定路由
This commit is contained in:
		@@ -5,6 +5,7 @@ export enum EnumRoutePath {
 | 
			
		||||
  'not-found' = '/404',
 | 
			
		||||
  'no-permission' = '/403',
 | 
			
		||||
  'service-error' = '/500',
 | 
			
		||||
  'reload' = '/reload',
 | 
			
		||||
  // 自定义路由
 | 
			
		||||
  'dashboard' = '/dashboard',
 | 
			
		||||
  'dashboard-analysis' = '/dashboard/analysis',
 | 
			
		||||
@@ -22,6 +23,8 @@ export enum EnumRouteTitle {
 | 
			
		||||
  'not-found' = '未找到',
 | 
			
		||||
  'no-permission' = '无权限',
 | 
			
		||||
  'service-error' = '服务器错误',
 | 
			
		||||
  'reload' = '重载',
 | 
			
		||||
  // 自定义路由
 | 
			
		||||
  'dashboard' = '仪表盘',
 | 
			
		||||
  'dashboard-analysis' = '分析页',
 | 
			
		||||
  'dashboard-workbench' = '工作台',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { useRouter, useRoute } from 'vue-router';
 | 
			
		||||
import type { RouteLocationRaw } from 'vue-router';
 | 
			
		||||
import { EnumRoutePath } from '@/enum';
 | 
			
		||||
import { router as globalRouter, RouteNameMap } from '@/router';
 | 
			
		||||
import type { LoginModuleType } from '@/interface';
 | 
			
		||||
 | 
			
		||||
@@ -61,9 +62,14 @@ export default function useRouterChange(inSetup: boolean = true) {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function toReload(redirectUrl: string) {
 | 
			
		||||
    router.push({ path: EnumRoutePath.reload, query: { redirectUrl } });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    toHome,
 | 
			
		||||
    toLogin,
 | 
			
		||||
    toCurrentLogin
 | 
			
		||||
    toCurrentLogin,
 | 
			
		||||
    toReload
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,13 +15,13 @@ export interface ThemeSettings {
 | 
			
		||||
  menuStyle: MenuStyle;
 | 
			
		||||
  /** 头部样式 */
 | 
			
		||||
  headerStyle: HeaderStyle;
 | 
			
		||||
  /** 多标签样式 */
 | 
			
		||||
  /** 多页签样式 */
 | 
			
		||||
  multiTabStyle: MultiTabStyle;
 | 
			
		||||
  /** 面包屑样式 */
 | 
			
		||||
  crumbsStyle: CrumbsStyle;
 | 
			
		||||
  /** 页面样式 */
 | 
			
		||||
  pageStyle: PageStyle;
 | 
			
		||||
  /** 固定头部和多标签 */
 | 
			
		||||
  /** 固定头部和多页签 */
 | 
			
		||||
  fixedHeaderAndTab: boolean;
 | 
			
		||||
  /** 显示重载按钮 */
 | 
			
		||||
  showReload: boolean;
 | 
			
		||||
@@ -70,9 +70,9 @@ interface MenuStyle {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface MultiTabStyle {
 | 
			
		||||
  /** 多标签高度 */
 | 
			
		||||
  /** 多页签高度 */
 | 
			
		||||
  height: number;
 | 
			
		||||
  /** 多标签可见 */
 | 
			
		||||
  /** 多页签可见 */
 | 
			
		||||
  visible: boolean;
 | 
			
		||||
  /** 背景颜色 */
 | 
			
		||||
  bgColor: string;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,33 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div v-if="fixedHeaderAndTab && theme.navStyle.mode !== 'horizontal-mix'" class="multi-tab-height w-full"></div>
 | 
			
		||||
  <div
 | 
			
		||||
    class="multi-tab-height flex-y-center w-full px-10px"
 | 
			
		||||
    class="multi-tab-height flex-y-center justify-between w-full px-10px"
 | 
			
		||||
    :class="{ 'multi-tab-top absolute': fixedHeaderAndTab, 'bg-[#f5f7f9]': !theme.darkMode }"
 | 
			
		||||
    :style="{ zIndex }"
 | 
			
		||||
  >
 | 
			
		||||
    <n-space :align="'center'">
 | 
			
		||||
      <n-tag>爱在西元前</n-tag>
 | 
			
		||||
      <n-tag type="success">不该</n-tag>
 | 
			
		||||
      <n-tag type="warning">超人不会飞</n-tag>
 | 
			
		||||
      <n-tag type="error">手写的从前</n-tag>
 | 
			
		||||
      <n-tag type="info">哪里都是你</n-tag>
 | 
			
		||||
      <n-gradient-text size="24">这是MultiTab组件</n-gradient-text>
 | 
			
		||||
      <n-tag
 | 
			
		||||
        v-for="item in app.multiTab.routes"
 | 
			
		||||
        :key="item.path"
 | 
			
		||||
        :type="app.multiTab.activeRoute === item.fullPath ? 'primary' : 'default'"
 | 
			
		||||
        class="cursor-pointer"
 | 
			
		||||
        @click="handleClickTab(item.fullPath)"
 | 
			
		||||
      >
 | 
			
		||||
        {{ item.meta?.title }}
 | 
			
		||||
      </n-tag>
 | 
			
		||||
    </n-space>
 | 
			
		||||
    <div class="flex-center w-32px h-32px bg-white cursor-pointer" @click="handleReload">
 | 
			
		||||
      <icon-mdi-refresh class="text-16px" />
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { computed } from 'vue';
 | 
			
		||||
import { NSpace, NTag, NGradientText } from 'naive-ui';
 | 
			
		||||
import { useThemeStore } from '@/store';
 | 
			
		||||
import { computed, watch } from 'vue';
 | 
			
		||||
import { useRoute } from 'vue-router';
 | 
			
		||||
import { NSpace, NTag } from 'naive-ui';
 | 
			
		||||
import { useThemeStore, useAppStore } from '@/store';
 | 
			
		||||
import { useRouterChange } from '@/hooks';
 | 
			
		||||
 | 
			
		||||
defineProps({
 | 
			
		||||
  zIndex: {
 | 
			
		||||
@@ -28,7 +36,11 @@ defineProps({
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const route = useRoute();
 | 
			
		||||
const theme = useThemeStore();
 | 
			
		||||
const app = useAppStore();
 | 
			
		||||
const { initMultiTab, addMultiTab, setActiveMultiTab, handleClickTab } = useAppStore();
 | 
			
		||||
const { toReload } = useRouterChange();
 | 
			
		||||
 | 
			
		||||
const fixedHeaderAndTab = computed(() => theme.fixedHeaderAndTab || theme.navStyle.mode === 'horizontal-mix');
 | 
			
		||||
const multiTabHeight = computed(() => {
 | 
			
		||||
@@ -39,6 +51,25 @@ const headerHeight = computed(() => {
 | 
			
		||||
  const { height } = theme.headerStyle;
 | 
			
		||||
  return `${height}px`;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function handleReload() {
 | 
			
		||||
  toReload(route.fullPath);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function init() {
 | 
			
		||||
  initMultiTab();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
  () => route.fullPath,
 | 
			
		||||
  newValue => {
 | 
			
		||||
    addMultiTab(route);
 | 
			
		||||
    setActiveMultiTab(newValue);
 | 
			
		||||
  }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
// 初始化
 | 
			
		||||
init();
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
.multi-tab-height {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <setting-menu-item label="分割菜单">
 | 
			
		||||
      <n-switch :value="theme.menuStyle.splitMenu" @update:value="handleSplitMenu" />
 | 
			
		||||
    </setting-menu-item>
 | 
			
		||||
    <setting-menu-item label="固定头部和多标签">
 | 
			
		||||
    <setting-menu-item label="固定头部和多页签">
 | 
			
		||||
      <n-switch :value="splitMenu" :disabled="disabledSplitMenu" @update:value="handleFixedHeaderAndTab" />
 | 
			
		||||
    </setting-menu-item>
 | 
			
		||||
    <setting-menu-item label="头部高度">
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
        @update:value="handleHeaderHeight"
 | 
			
		||||
      />
 | 
			
		||||
    </setting-menu-item>
 | 
			
		||||
    <setting-menu-item label="多标签高度">
 | 
			
		||||
    <setting-menu-item label="多页签高度">
 | 
			
		||||
      <n-input-number
 | 
			
		||||
        class="w-120px"
 | 
			
		||||
        size="small"
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <setting-menu-item label="面包屑图标">
 | 
			
		||||
      <n-switch :value="theme.crumbsStyle.showIcon" @update:value="handleCrumbsIconVisible" />
 | 
			
		||||
    </setting-menu-item>
 | 
			
		||||
    <setting-menu-item label="多标签">
 | 
			
		||||
    <setting-menu-item label="多页签">
 | 
			
		||||
      <n-switch :value="theme.multiTabStyle.visible" @update:value="handleMultiTabVisible" />
 | 
			
		||||
    </setting-menu-item>
 | 
			
		||||
    <setting-menu-item label="页面切换动画">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,3 @@
 | 
			
		||||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';
 | 
			
		||||
import type { App } from 'vue';
 | 
			
		||||
import type { RouteRecordRaw } from 'vue-router';
 | 
			
		||||
import { constantRoutes, customRoutes, RouteNameMap } from './routes';
 | 
			
		||||
import createRouterGuide from './permission';
 | 
			
		||||
 | 
			
		||||
const routes: Array<RouteRecordRaw> = [...customRoutes, ...constantRoutes];
 | 
			
		||||
 | 
			
		||||
/** 用于部署vercel托管服务 */
 | 
			
		||||
const isVercel = import.meta.env.VITE_HTTP_ENV === 'VERCEL';
 | 
			
		||||
 | 
			
		||||
export const router = createRouter({
 | 
			
		||||
  history: isVercel ? createWebHashHistory() : createWebHistory(),
 | 
			
		||||
  routes
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export async function setupRouter(app: App) {
 | 
			
		||||
  app.use(router);
 | 
			
		||||
  createRouterGuide(router);
 | 
			
		||||
  await router.isReady();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { RouteNameMap };
 | 
			
		||||
export { router, setupRouter } from './setup';
 | 
			
		||||
export { RouteNameMap, ROUTE_HOME, customRoutes } from './routes';
 | 
			
		||||
export { menus } from './menus';
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ const loginModuleRegExp = getLoginModuleRegExp();
 | 
			
		||||
 * 固定不变的路由
 | 
			
		||||
 * @description !最后一项重定向未找到的路由须放置路由的最后一项
 | 
			
		||||
 */
 | 
			
		||||
export const constantRoutes: RouteRecordRaw[] = [
 | 
			
		||||
const constantRoutes: RouteRecordRaw[] = [
 | 
			
		||||
  {
 | 
			
		||||
    name: RouteNameMap.get('system'),
 | 
			
		||||
    path: EnumRoutePath.system,
 | 
			
		||||
@@ -82,6 +82,17 @@ export const constantRoutes: RouteRecordRaw[] = [
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/** 路由首页 */
 | 
			
		||||
export const ROUTE_HOME: CustomRoute = {
 | 
			
		||||
  name: RouteNameMap.get('dashboard-analysis'),
 | 
			
		||||
  path: EnumRoutePath['dashboard-analysis'],
 | 
			
		||||
  component: () => import('@/views/dashboard/analysis/index.vue'),
 | 
			
		||||
  meta: {
 | 
			
		||||
    requiresAuth: true,
 | 
			
		||||
    title: EnumRouteTitle['dashboard-analysis']
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 自定义路由
 | 
			
		||||
 */
 | 
			
		||||
@@ -89,10 +100,24 @@ export const customRoutes: CustomRoute[] = [
 | 
			
		||||
  {
 | 
			
		||||
    name: RouteNameMap.get('root'),
 | 
			
		||||
    path: EnumRoutePath.root,
 | 
			
		||||
    redirect: { name: RouteNameMap.get('dashboard-analysis') },
 | 
			
		||||
    component: BasicLayout,
 | 
			
		||||
    redirect: { name: ROUTE_HOME.name },
 | 
			
		||||
    meta: {
 | 
			
		||||
      isNotMenu: true
 | 
			
		||||
    }
 | 
			
		||||
    },
 | 
			
		||||
    children: [
 | 
			
		||||
      // 重载
 | 
			
		||||
      {
 | 
			
		||||
        name: RouteNameMap.get('reload'),
 | 
			
		||||
        path: EnumRoutePath.reload,
 | 
			
		||||
        component: () => import('@/views/system/reload/index.vue'),
 | 
			
		||||
        meta: {
 | 
			
		||||
          title: EnumRouteTitle.reload,
 | 
			
		||||
          isNotMenu: true,
 | 
			
		||||
          fullPage: true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: RouteNameMap.get('dashboard'),
 | 
			
		||||
@@ -105,15 +130,7 @@ export const customRoutes: CustomRoute[] = [
 | 
			
		||||
      icon: Dashboard
 | 
			
		||||
    },
 | 
			
		||||
    children: [
 | 
			
		||||
      {
 | 
			
		||||
        name: RouteNameMap.get('dashboard-analysis'),
 | 
			
		||||
        path: EnumRoutePath['dashboard-analysis'],
 | 
			
		||||
        component: () => import('@/views/dashboard/analysis/index.vue'),
 | 
			
		||||
        meta: {
 | 
			
		||||
          requiresAuth: true,
 | 
			
		||||
          title: EnumRouteTitle['dashboard-analysis']
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      ROUTE_HOME,
 | 
			
		||||
      {
 | 
			
		||||
        name: RouteNameMap.get('dashboard-workbench'),
 | 
			
		||||
        path: EnumRoutePath['dashboard-workbench'],
 | 
			
		||||
@@ -169,10 +186,5 @@ export const customRoutes: CustomRoute[] = [
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/** 路由白名单(不需要登录) */
 | 
			
		||||
export const whitelistRoutes: string[] = [
 | 
			
		||||
  RouteNameMap.get('login')!,
 | 
			
		||||
  RouteNameMap.get('exception-403')!,
 | 
			
		||||
  RouteNameMap.get('exception-404')!,
 | 
			
		||||
  RouteNameMap.get('exception-500')!
 | 
			
		||||
];
 | 
			
		||||
/** 所有路由 */
 | 
			
		||||
export const routes: RouteRecordRaw[] = [...customRoutes, ...constantRoutes];
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								src/router/setup.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/router/setup.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';
 | 
			
		||||
import type { App } from 'vue';
 | 
			
		||||
import { routes } from './routes';
 | 
			
		||||
import createRouterGuide from './permission';
 | 
			
		||||
 | 
			
		||||
/** 用于部署vercel托管服务 */
 | 
			
		||||
const isVercel = import.meta.env.VITE_HTTP_ENV === 'VERCEL';
 | 
			
		||||
 | 
			
		||||
export const router = createRouter({
 | 
			
		||||
  history: isVercel ? createWebHashHistory() : createWebHistory(),
 | 
			
		||||
  routes
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export async function setupRouter(app: App) {
 | 
			
		||||
  app.use(router);
 | 
			
		||||
  createRouterGuide(router);
 | 
			
		||||
  await router.isReady();
 | 
			
		||||
}
 | 
			
		||||
@@ -48,7 +48,7 @@ const themeSettings: ThemeSettings = {
 | 
			
		||||
    bgColor: '#fff'
 | 
			
		||||
  },
 | 
			
		||||
  multiTabStyle: {
 | 
			
		||||
    height: 48,
 | 
			
		||||
    height: 44,
 | 
			
		||||
    visible: true,
 | 
			
		||||
    bgColor: '#fff'
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,15 @@
 | 
			
		||||
import { defineStore } from 'pinia';
 | 
			
		||||
import { nextTick } from 'vue';
 | 
			
		||||
import type { RouteLocationNormalizedLoaded } from 'vue-router';
 | 
			
		||||
import { store } from '@/store';
 | 
			
		||||
import { router, ROUTE_HOME } from '@/router';
 | 
			
		||||
 | 
			
		||||
/** app状态 */
 | 
			
		||||
interface AppState {
 | 
			
		||||
  menu: MenuState;
 | 
			
		||||
  multiTab: MultiTab;
 | 
			
		||||
  /** 重新加载标记 */
 | 
			
		||||
  reloadFlag: boolean;
 | 
			
		||||
  settingDrawer: SettingDrawer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -15,8 +19,15 @@ interface MenuState {
 | 
			
		||||
  collapsed: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MultiTabRoute = Partial<RouteLocationNormalizedLoaded> & {
 | 
			
		||||
  path: string;
 | 
			
		||||
  fullPath: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** 多页签 */
 | 
			
		||||
interface MultiTab {
 | 
			
		||||
  routes: RouteLocationNormalizedLoaded[];
 | 
			
		||||
  routes: MultiTabRoute[];
 | 
			
		||||
  activeRoute: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 项目配置抽屉的状态 */
 | 
			
		||||
@@ -32,8 +43,10 @@ const appStore = defineStore({
 | 
			
		||||
      collapsed: false
 | 
			
		||||
    },
 | 
			
		||||
    multiTab: {
 | 
			
		||||
      routes: []
 | 
			
		||||
      routes: [],
 | 
			
		||||
      activeRoute: ''
 | 
			
		||||
    },
 | 
			
		||||
    reloadFlag: true,
 | 
			
		||||
    settingDrawer: {
 | 
			
		||||
      visible: false
 | 
			
		||||
    }
 | 
			
		||||
@@ -47,9 +60,59 @@ const appStore = defineStore({
 | 
			
		||||
    toggleMenu() {
 | 
			
		||||
      this.menu.collapsed = !this.menu.collapsed;
 | 
			
		||||
    },
 | 
			
		||||
    /** 判断tab路由是否存在某个路由 */
 | 
			
		||||
    getIndexInTabRoutes(fullPath: string) {
 | 
			
		||||
      return this.multiTab.routes.findIndex(item => item.fullPath === fullPath);
 | 
			
		||||
    },
 | 
			
		||||
    /** 添加多tab的数据 */
 | 
			
		||||
    addMultiTab(route: RouteLocationNormalizedLoaded) {
 | 
			
		||||
      this.multiTab.routes.push(route);
 | 
			
		||||
      const { fullPath } = route;
 | 
			
		||||
      const isExist = this.getIndexInTabRoutes(fullPath) > -1;
 | 
			
		||||
      if (!isExist) {
 | 
			
		||||
        this.multiTab.routes.push({ ...route });
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    handleClickTab(fullPath: string) {
 | 
			
		||||
      if (this.multiTab.activeRoute !== fullPath) {
 | 
			
		||||
        router.push(fullPath);
 | 
			
		||||
        this.setActiveMultiTab(fullPath);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    /** 设置当前路由对应的tab为激活状态 */
 | 
			
		||||
    setActiveMultiTab(fullPath: string) {
 | 
			
		||||
      this.multiTab.activeRoute = fullPath;
 | 
			
		||||
    },
 | 
			
		||||
    /** 获取路由首页信息 */
 | 
			
		||||
    getHomeTabRoute(route: RouteLocationNormalizedLoaded, isHome: boolean) {
 | 
			
		||||
      const { name, path, meta } = ROUTE_HOME;
 | 
			
		||||
      const home: MultiTabRoute = {
 | 
			
		||||
        name,
 | 
			
		||||
        path,
 | 
			
		||||
        fullPath: path,
 | 
			
		||||
        meta
 | 
			
		||||
      };
 | 
			
		||||
      if (isHome) {
 | 
			
		||||
        Object.assign(home, route);
 | 
			
		||||
      }
 | 
			
		||||
      return home;
 | 
			
		||||
    },
 | 
			
		||||
    /** 初始化多页签数据 */
 | 
			
		||||
    initMultiTab() {
 | 
			
		||||
      const { currentRoute } = router;
 | 
			
		||||
      const isHome = currentRoute.value.name === ROUTE_HOME.name;
 | 
			
		||||
      const home = this.getHomeTabRoute(currentRoute.value, isHome);
 | 
			
		||||
      const routes = [home];
 | 
			
		||||
      if (!isHome) {
 | 
			
		||||
        routes.push(currentRoute.value);
 | 
			
		||||
      }
 | 
			
		||||
      this.multiTab.routes = routes;
 | 
			
		||||
      this.setActiveMultiTab(currentRoute.value.fullPath);
 | 
			
		||||
    },
 | 
			
		||||
    /** 重新加载页面 */
 | 
			
		||||
    async handleReload() {
 | 
			
		||||
      this.reloadFlag = false;
 | 
			
		||||
      await nextTick();
 | 
			
		||||
      this.reloadFlag = true;
 | 
			
		||||
    },
 | 
			
		||||
    /** 打开配置抽屉 */
 | 
			
		||||
    openSettingDrawer() {
 | 
			
		||||
 
 | 
			
		||||
@@ -97,7 +97,7 @@ const themeStore = defineStore({
 | 
			
		||||
        this.multiTabStyle.height = height;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    /** 设置多标签的显示 */
 | 
			
		||||
    /** 设置多页签的显示 */
 | 
			
		||||
    handleMultiTabVisible(visible: boolean) {
 | 
			
		||||
      this.multiTabStyle.visible = visible;
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								src/views/system/reload/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/views/system/reload/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div></div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { useRoute, useRouter } from 'vue-router';
 | 
			
		||||
 | 
			
		||||
const { query } = useRoute();
 | 
			
		||||
const router = useRouter();
 | 
			
		||||
 | 
			
		||||
function init() {
 | 
			
		||||
  const redirect = (query.redirectUrl as string) || '/';
 | 
			
		||||
  router.replace(redirect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
init();
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped></style>
 | 
			
		||||
		Reference in New Issue
	
	Block a user