BaseLayout.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <script setup lang="ts">
  2. import settings from '@/api/settings'
  3. import PageHeader from '@/components/PageHeader/PageHeader.vue'
  4. import { setupIndexStatus } from '@/composables/useIndexStatus'
  5. import { useSettingsStore } from '@/pinia'
  6. import _ from 'lodash'
  7. import { storeToRefs } from 'pinia'
  8. import FooterLayout from './FooterLayout.vue'
  9. import HeaderLayout from './HeaderLayout.vue'
  10. import SideBar from './SideBar.vue'
  11. const drawerVisible = ref(false)
  12. const collapsed = ref(false)
  13. const hideLayoutSidebar = ref(false)
  14. function _init() {
  15. collapsed.value = collapse()
  16. hideLayoutSidebar.value = getClientWidth() < 600
  17. }
  18. const init = _.throttle(_init, 50)
  19. onMounted(init)
  20. addEventListener('resize', init)
  21. onUnmounted(() => {
  22. removeEventListener('resize', init)
  23. })
  24. function getClientWidth() {
  25. return document.body.clientWidth
  26. }
  27. function collapse() {
  28. return getClientWidth() < 1080
  29. }
  30. const { server_name } = storeToRefs(useSettingsStore())
  31. settings.get_server_name().then(r => {
  32. server_name.value = r.name
  33. })
  34. setupIndexStatus()
  35. const breadList = ref([])
  36. provide('breadList', breadList)
  37. </script>
  38. <template>
  39. <ALayout class="full-screen-wrapper min-h-screen">
  40. <div class="drawer-sidebar">
  41. <ADrawer
  42. v-model:open="drawerVisible"
  43. :closable="false"
  44. placement="left"
  45. width="256"
  46. @close="drawerVisible = false"
  47. >
  48. <SideBar />
  49. </ADrawer>
  50. </div>
  51. <ALayoutSider
  52. v-if="!hideLayoutSidebar"
  53. v-model:collapsed="collapsed"
  54. collapsible
  55. :style="{ zIndex: 11 }"
  56. theme="light"
  57. class="layout-sider"
  58. >
  59. <SideBar />
  60. </ALayoutSider>
  61. <ALayout class="main-container">
  62. <ALayoutHeader :style="{ position: 'sticky', top: '0', zIndex: 10, width: '100%' }">
  63. <HeaderLayout @click-un-fold="drawerVisible = true" />
  64. </ALayoutHeader>
  65. <ALayoutContent>
  66. <PageHeader />
  67. <div class="router-view">
  68. <RouterView v-slot="{ Component, route }">
  69. <Transition name="slide-fade">
  70. <component
  71. :is="Component"
  72. :key="route.path"
  73. />
  74. </Transition>
  75. </RouterView>
  76. </div>
  77. </ALayoutContent>
  78. <ALayoutFooter>
  79. <FooterLayout />
  80. </ALayoutFooter>
  81. </ALayout>
  82. </ALayout>
  83. </template>
  84. <style lang="less" scoped>
  85. .layout-sider {
  86. @media (max-width: 600px) {
  87. display: none;
  88. }
  89. }
  90. .drawer-sidebar {
  91. @media (min-width: 600px) {
  92. display: none;
  93. }
  94. }
  95. </style>
  96. <style lang="less">
  97. .layout-sider .sidebar {
  98. ul.ant-menu-inline.ant-menu-root {
  99. height: calc(100vh - 160px);
  100. overflow-y: auto;
  101. overflow-x: hidden;
  102. .ant-menu-item {
  103. width: unset;
  104. }
  105. }
  106. ul.ant-menu-inline-collapsed {
  107. height: calc(100vh - 200px);
  108. overflow-y: auto;
  109. overflow-x: hidden;
  110. }
  111. }
  112. </style>
  113. <style lang="less">
  114. .slide-fade-enter-active {
  115. transition: all .3s ease-in-out;
  116. }
  117. .slide-fade-leave-active {
  118. transition: all .3s cubic-bezier(1.0, 0.5, 0.8, 1.0);
  119. }
  120. .slide-fade-enter-from, .slide-fade-enter-to, .slide-fade-leave-to
  121. /* .slide-fade-leave-active for below version 2.1.8 */ {
  122. transform: translateX(10px);
  123. opacity: 0;
  124. }
  125. body {
  126. overflow: unset !important;
  127. }
  128. .ant-layout-header {
  129. padding: 0 !important;
  130. }
  131. .ant-layout-sider {
  132. &.ant-layout-sider-has-trigger {
  133. padding-bottom: 0;
  134. }
  135. box-shadow: 2px 0 8px rgba(29, 35, 41, 0.05);
  136. }
  137. .ant-drawer-body {
  138. .sidebar .logo {
  139. box-shadow: 0 1px 0 0 #e8e8e8;
  140. }
  141. .ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left {
  142. border-right: 0 !important;
  143. }
  144. }
  145. .ant-table-small {
  146. font-size: 13px;
  147. }
  148. .header-notice-wrapper .ant-tabs-content {
  149. max-height: 250px;
  150. }
  151. .header-notice-wrapper .ant-tabs-tabpane-active {
  152. overflow-y: scroll;
  153. }
  154. .ant-layout-footer {
  155. @media (max-width: 320px) {
  156. padding: 10px;
  157. }
  158. }
  159. .ant-layout-content {
  160. min-height: auto;
  161. .router-view {
  162. padding: 20px;
  163. @media (max-width: 512px) {
  164. padding: 20px 0;
  165. }
  166. position: relative;
  167. }
  168. }
  169. .ant-layout-footer {
  170. text-align: center;
  171. }
  172. </style>