default-layout.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <template>
  2. <a-layout class="layout" :class="{ mobile: appStore.hideMenu }">
  3. <div v-if="navbar" class="layout-navbar">
  4. <NavBar />
  5. </div>
  6. <a-layout>
  7. <a-layout>
  8. <a-layout-sider
  9. v-if="renderMenu"
  10. v-show="!hideMenu"
  11. class="layout-sider"
  12. breakpoint="xl"
  13. :collapsed="collapsed"
  14. :collapsible="true"
  15. :width="menuWidth"
  16. :style="{ paddingTop: navbar ? '10px' : '' }"
  17. :hide-trigger="true"
  18. @collapse="setCollapsed"
  19. >
  20. <div class="left-side">
  21. <a-space>
  22. <img
  23. class="logo"
  24. alt="logo"
  25. src="//p3-armor.byteimg.com/tos-cn-i-49unhts6dw/dfdba5317c0c20ce20e64fac803d52bc.svg~tplv-49unhts6dw-image.image"
  26. />
  27. <a-typography-title
  28. :style="{ fontSize: '18px' }"
  29. :heading="5"
  30. v-if="!collapsed"
  31. >
  32. SMMS
  33. </a-typography-title>
  34. </a-space>
  35. </div>
  36. <div class="menu-wrapper">
  37. <Menu />
  38. </div>
  39. </a-layout-sider>
  40. <a-drawer
  41. v-if="hideMenu"
  42. :visible="drawerVisible"
  43. placement="left"
  44. :footer="false"
  45. mask-closable
  46. :closable="false"
  47. @cancel="drawerCancel"
  48. >
  49. <Menu />
  50. </a-drawer>
  51. <a-layout class="layout-content" :style="paddingStyle">
  52. <TabBar v-if="appStore.tabBar" />
  53. <a-layout-content>
  54. <PageLayout />
  55. </a-layout-content>
  56. <Footer v-if="footer" />
  57. </a-layout>
  58. </a-layout>
  59. </a-layout>
  60. </a-layout>
  61. </template>
  62. <script lang="ts" setup>
  63. import { ref, computed, watch, provide, onMounted } from 'vue';
  64. import { useRouter, useRoute } from 'vue-router';
  65. import { useAppStore, useUserStore } from '@/store';
  66. import NavBar from '@/components/navbar/index.vue';
  67. import Menu from '@/components/menu/index.vue';
  68. import Footer from '@/components/footer/index.vue';
  69. import TabBar from '@/components/tab-bar/index.vue';
  70. import usePermission from '@/hooks/permission';
  71. import useResponsive from '@/hooks/responsive';
  72. import PageLayout from './page-layout.vue';
  73. const isInit = ref(false);
  74. const appStore = useAppStore();
  75. const userStore = useUserStore();
  76. const router = useRouter();
  77. const route = useRoute();
  78. const permission = usePermission();
  79. useResponsive(true);
  80. const navbarHeight = `50px`;
  81. const navbar = computed(() => appStore.navbar);
  82. const renderMenu = computed(() => appStore.menu && !appStore.topMenu);
  83. const hideMenu = computed(() => appStore.hideMenu);
  84. const footer = computed(() => appStore.footer);
  85. const menuWidth = computed(() => {
  86. return appStore.menuCollapse ? 48 : appStore.menuWidth;
  87. });
  88. const collapsed = computed(() => {
  89. return appStore.menuCollapse;
  90. });
  91. const paddingStyle = computed(() => {
  92. const paddingLeft =
  93. renderMenu.value && !hideMenu.value
  94. ? { paddingLeft: `${menuWidth.value}px` }
  95. : {};
  96. const paddingTop = navbar.value ? { paddingTop: navbarHeight } : {};
  97. return { ...paddingLeft, ...paddingTop };
  98. });
  99. const setCollapsed = (val: boolean) => {
  100. if (!isInit.value) return; // for page initialization menu state problem
  101. appStore.updateSettings({ menuCollapse: val });
  102. };
  103. watch(
  104. () => userStore.role,
  105. roleValue => {
  106. if (roleValue && !permission.accessRouter(route))
  107. router.push({ name: 'notFound' });
  108. }
  109. );
  110. const drawerVisible = ref(false);
  111. const drawerCancel = () => {
  112. drawerVisible.value = false;
  113. };
  114. provide('toggleDrawerMenu', () => {
  115. drawerVisible.value = !drawerVisible.value;
  116. });
  117. onMounted(() => {
  118. isInit.value = true;
  119. });
  120. </script>
  121. <style scoped lang="less">
  122. @nav-size-height: 50px;
  123. @layout-max-width: 1100px;
  124. .layout {
  125. width: 100%;
  126. height: 100%;
  127. }
  128. .layout-navbar {
  129. position: fixed;
  130. top: 0;
  131. left: 0;
  132. z-index: 99;
  133. display: flex;
  134. justify-content: end;
  135. width: 100%;
  136. height: @nav-size-height;
  137. background-color: white;
  138. }
  139. .layout-sider {
  140. position: fixed;
  141. top: 0;
  142. left: 0;
  143. z-index: 100;
  144. height: 100%;
  145. transition: all 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
  146. &::after {
  147. position: absolute;
  148. top: 0;
  149. right: -1px;
  150. display: block;
  151. width: 1px;
  152. height: 100%;
  153. background-color: var(--color-border);
  154. content: '';
  155. }
  156. > :deep(.arco-layout-sider-children) {
  157. overflow-y: hidden;
  158. }
  159. }
  160. .left-side {
  161. display: flex;
  162. align-items: center;
  163. width: 180px;
  164. height: 30px;
  165. padding-left: 10px;
  166. overflow: hidden;
  167. .logo {
  168. margin-right: 10px;
  169. }
  170. }
  171. .menu-wrapper {
  172. height: 100%;
  173. overflow: auto;
  174. overflow-x: hidden;
  175. :deep(.arco-menu) {
  176. ::-webkit-scrollbar {
  177. width: 12px;
  178. height: 4px;
  179. }
  180. ::-webkit-scrollbar-thumb {
  181. background-color: var(--color-text-4);
  182. background-clip: padding-box;
  183. border: 4px solid transparent;
  184. border-radius: 7px;
  185. }
  186. ::-webkit-scrollbar-thumb:hover {
  187. background-color: var(--color-text-3);
  188. }
  189. }
  190. }
  191. .layout-content {
  192. min-height: 100vh;
  193. overflow-y: hidden;
  194. background-color: var(--color-fill-2);
  195. transition: padding 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
  196. }
  197. </style>