index.vue 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <script lang="ts">
  2. import { EMitt, ESidebarLayoutEnum, EThemeSetting } from "@/constants/enum";
  3. import emits from "@/utils/emits";
  4. import { getThemeConfigCache, getThemeConfigCacheByKey, getThemeConfigToClass } from "@/utils/theme";
  5. import { getValueByKeys } from "@/utils/utils";
  6. import { useMediaQuery } from "@vueuse/core";
  7. import { computed, defineComponent, reactive } from "vue";
  8. import { RouteRecordRaw, useRouter } from "vue-router";
  9. import { useAppStore } from "@/store";
  10. import BaseHeader from "./header/base-header.vue";
  11. import BaseSidebar from "./sidebar/base-sidebar.vue";
  12. import MobileSidebar from "./sidebar/mobile-sidebar.vue";
  13. import BaseView from "./view/base-view.vue";
  14. /**
  15. * 多标签页布局
  16. */
  17. export default defineComponent({
  18. name: "Layout",
  19. components: { BaseView, BaseHeader, BaseSidebar, MobileSidebar },
  20. setup() {
  21. const isMobile = useMediaQuery("(max-width: 768px)");
  22. const themeCache = getThemeConfigCache();
  23. const sidebarLayoutCache = getThemeConfigCacheByKey(EThemeSetting.NavLayout, themeCache);
  24. const router = useRouter();
  25. const store = useAppStore();
  26. const state = reactive({
  27. isShowNav: sidebarLayoutCache !== ESidebarLayoutEnum.Top,
  28. sidebarLayout: sidebarLayoutCache,
  29. themeClass: getThemeConfigToClass(themeCache),
  30. loading: false,
  31. mixLayoutRoutes: router.options.routes.find((x: RouteRecordRaw) => x.path === "/")?.children ?? ([] as RouteRecordRaw[])
  32. });
  33. const containerClassNames = computed(() =>
  34. Object.values(state.themeClass)
  35. .concat(isMobile.value ? ["ui-mobile"] : [])
  36. .join(" ")
  37. );
  38. emits.on(EMitt.OnSelectHeaderNavMenusByMixNav, (path) => {
  39. state.mixLayoutRoutes = store.state.routes.find((x: RouteRecordRaw) => x.path === path)?.children ?? [];
  40. });
  41. emits.on(EMitt.OnSetTheme, ([type, value]) => {
  42. state.themeClass[type] = "ui-" + value;
  43. });
  44. emits.on(EMitt.OnSetNavLayout, (vl) => {
  45. state.sidebarLayout = vl;
  46. state.isShowNav = vl !== ESidebarLayoutEnum.Top;
  47. if (vl === ESidebarLayoutEnum.Mix) {
  48. const currRoute = getValueByKeys(getValueByKeys(router.currentRoute.value.meta, "matched", [])[0], "path", "");
  49. state.mixLayoutRoutes = store.state.routes.find((x: RouteRecordRaw) => x.path === currRoute)?.children ?? [];
  50. }
  51. });
  52. emits.on(EMitt.OnLoading, (vl) => {
  53. state.loading = vl;
  54. });
  55. return { state, ESidebarLayoutEnum, containerClassNames };
  56. }
  57. });
  58. </script>
  59. <template>
  60. <el-container :class="`rr ${containerClassNames}`" v-loading="state.loading" element-loading-background="#0000" element-loading-lock="true" element-loading-custom-class="rr-loading">
  61. <el-header class="rr-header" height="50px">
  62. <base-header></base-header>
  63. </el-header>
  64. <el-container class="rr-body">
  65. <el-aside v-if="state.isShowNav" class="rr-sidebar hidden-xs-only" width="auto">
  66. <base-sidebar v-if="state.sidebarLayout === ESidebarLayoutEnum.Left" :router="true" mode="vertical" :is-mobile="false"></base-sidebar>
  67. <base-sidebar v-else :menus="state.mixLayoutRoutes" :router="true" mode="vertical" :is-mobile="false"></base-sidebar>
  68. </el-aside>
  69. <div class="rr-sidebar rr-sidebar-mobile hidden-sm-and-up show-xs-only">
  70. <mobile-sidebar></mobile-sidebar>
  71. </div>
  72. <el-container class="rr-view-container">
  73. <el-main class="rr-view">
  74. <base-view></base-view>
  75. </el-main>
  76. </el-container>
  77. </el-container>
  78. </el-container>
  79. </template>