index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template>
  2. <a-button
  3. v-if="isMobile"
  4. class="open-icon"
  5. type="primary"
  6. @click="openDrawer"
  7. >
  8. <right-outlined />
  9. </a-button>
  10. <a-drawer
  11. placement="left"
  12. :closable="false"
  13. :open="drawerVisible"
  14. :get-container="false"
  15. :style="{ position: 'absolute' }"
  16. width="240px"
  17. @close="drawerVisible = false"
  18. >
  19. <a-layout-sider
  20. :trigger="null"
  21. v-model:collapsed="collapsed"
  22. collapsible
  23. :style="{backgroundColor: bgColor, overflow: 'hidden'}"
  24. >
  25. <a-menu
  26. v-model:selectedKeys="selectedKeys"
  27. :openKeys="openKeys"
  28. mode="inline"
  29. :style="{ borderRight: 0 }"
  30. >
  31. <sidebar-item
  32. :item="route"
  33. v-for="route in sidebarRoute"
  34. :key="route.path"
  35. :base-path="route.path"
  36. />
  37. </a-menu>
  38. </a-layout-sider>
  39. </a-drawer>
  40. <a-layout-sider
  41. v-if="!isMobile"
  42. :style="{backgroundColor: bgColor, overflow: 'hidden', overflowY: 'scroll', boxShadow: `0 1px 4px rgba(0,21,41,.12)`, paddingTop: '6px'}"
  43. breakpoint="lg"
  44. collapsible
  45. v-model:collapsed="collapsed"
  46. >
  47. <div class="logo" >
  48. <img :src="logoPng" alt="" v-if="logoPng">
  49. </div>
  50. <a-menu
  51. v-model:selectedKeys="selectedKeys"
  52. :openKeys="openKeys"
  53. mode="inline"
  54. :style="{ borderRight: 0 }"
  55. >
  56. <sidebar-item
  57. :item="route"
  58. v-for="route in sidebarRoute"
  59. :key="route.path"
  60. :base-path="route.path"
  61. />
  62. </a-menu>
  63. </a-layout-sider>
  64. </template>
  65. <script lang="ts" setup >
  66. import { ref, computed, watch, onMounted } from 'vue'
  67. import SidebarItem from './SidebarItem.vue'
  68. import { useRouter, useRoute } from 'vue-router'
  69. import { useDesignStore } from '@/store'
  70. import { useDeviceType } from '@/hooks'
  71. import { RightOutlined } from '@ant-design/icons-vue'
  72. import { routes } from '@/router/index'
  73. import AppConfig from 'AppConfig'
  74. import { useIsMicro } from '@/hooks/effect'
  75. const designStore = useDesignStore()
  76. const isMobile = useDeviceType()
  77. const bgColor = computed(() => designStore.theme ? '#141414' : '#fff')
  78. const route = useRoute()
  79. const router = useRouter()
  80. const collapsed = ref<boolean>(true)
  81. const logoPng = computed(() => collapsed.value ? AppConfig.logoContract : AppConfig.logoExpand)
  82. const sidebarRoute = ref<any>()
  83. const selectedKeys = ref<string[]>()
  84. const openKeys = ref<string[]>()
  85. const drawerVisible = ref<boolean>(false)
  86. const compatibleRoutes = !useIsMicro() ? router.getRoutes().filter(item => item.path !== '/cloudlink') : router.getRoutes()
  87. watch(
  88. () => route.path,
  89. () => {
  90. sidebarRoute.value = isMobile ? routes : router.getRoutes().find(item => item.path === route.matched[useIsMicro() ? 1 : 0].path)?.children
  91. selectedKeys.value = [route.path]
  92. openKeys.value = [route.matched[1].path]
  93. },
  94. {
  95. immediate: true
  96. }
  97. )
  98. const openDrawer = () => drawerVisible.value = true
  99. onMounted(() => {
  100. console.log('我渲染了嗎')
  101. })
  102. </script>
  103. <style lang="less" scoped >
  104. /deep/ .ant-layout-sider-children {
  105. margin-top: -4px;
  106. }
  107. .ant-layout-sider::-webkit-scrollbar {
  108. width: 0;
  109. }
  110. .logo {
  111. width: 100%;
  112. height: 53px;
  113. margin: 0px 0px;
  114. margin-top: 0px;
  115. display: flex;
  116. justify-content: center;
  117. align-items: center;
  118. background-color: transparent;
  119. img {
  120. width: 60%;
  121. height: 70%;
  122. }
  123. }
  124. .mobile-sider {
  125. width: 100vw;
  126. height: 100vh;
  127. background-color: rgba(0, 0, 0, 0.5);
  128. pointer-events: none;
  129. }
  130. .open-icon {
  131. width: 50px;
  132. height: 50px;
  133. position: fixed;
  134. top: 200px;
  135. left: 0px;
  136. z-index: 999;
  137. display: flex;
  138. justify-content: center;
  139. align-items: center;
  140. border-top-left-radius: 0px;
  141. border-bottom-left-radius: 0px;
  142. }
  143. /deep/ .ant-layout-sider-trigger {
  144. background-color: #fff !important;
  145. }
  146. </style>