index.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <script lang="ts" setup>
  2. import { useRoutesStore } from '@/store/modules/routes'
  3. import { useSettingsStore } from '@/store/modules/settings'
  4. import variables from '@vab/styles/variables/variables.module.scss'
  5. import { defaultOpeneds, uniqueOpened } from '@/config'
  6. const props = defineProps({
  7. layout: {
  8. type: String,
  9. default: 'vertical',
  10. },
  11. })
  12. const settingsStore = useSettingsStore()
  13. const { collapse } = storeToRefs(settingsStore)
  14. const routesStore = useRoutesStore()
  15. const {
  16. getRoutes: routes,
  17. getActiveMenu: activeMenu,
  18. getPartialRoutes: partialRoutes,
  19. } = storeToRefs(routesStore)
  20. const handleRoutes = computed(() => {
  21. return props.layout === 'comprehensive'
  22. ? partialRoutes.value
  23. : routes.value.flatMap((route: any) =>
  24. route.meta.levelHidden && route.children ? [...route.children] : route
  25. )
  26. })
  27. </script>
  28. <template>
  29. <el-scrollbar
  30. class="vab-side-bar"
  31. :class="{ 'is-collapse': collapse, 'side-bar-common': layout === 'common' }"
  32. >
  33. <vab-logo
  34. v-if="
  35. layout === 'vertical' ||
  36. layout === 'comprehensive' ||
  37. layout === 'float'
  38. "
  39. />
  40. <el-menu
  41. :active-text-color="variables['menu-color-active']"
  42. :background-color="variables['menu-background']"
  43. :collapse="collapse"
  44. :collapse-transition="false"
  45. :default-active="activeMenu.data"
  46. :default-openeds="defaultOpeneds"
  47. menu-trigger="click"
  48. mode="vertical"
  49. :text-color="variables['menu-color']"
  50. :unique-opened="uniqueOpened"
  51. >
  52. <template v-for="(item, index) in handleRoutes" :key="index + item.name">
  53. <vab-menu v-if="!item.meta.hidden" :item="item" />
  54. </template>
  55. </el-menu>
  56. </el-scrollbar>
  57. </template>
  58. <style lang="scss" scoped>
  59. @mixin active {
  60. &:hover {
  61. color: var(--el-color-white);
  62. background-color: $base-menu-active;
  63. }
  64. &.is-active {
  65. color: var(--el-color-white);
  66. background-color: $base-menu-active;
  67. }
  68. }
  69. .vab-side-bar {
  70. position: fixed;
  71. top: 0;
  72. bottom: 0;
  73. left: 0;
  74. z-index: $base-z-index + 1;
  75. width: var(--el-left-menu-width);
  76. height: 100vh;
  77. overflow: hidden;
  78. background: $base-menu-background;
  79. box-shadow: $base-box-shadow;
  80. transition: $base-transition;
  81. &.side-bar-common {
  82. top: $base-header-height;
  83. height: calc(100vh - #{$base-header-height});
  84. }
  85. &.is-collapse {
  86. width: $base-left-menu-width-min;
  87. border-right: 0;
  88. :deep() {
  89. .el-menu--collapse.el-menu {
  90. > .el-menu-item,
  91. > .el-sub-menu {
  92. text-align: center;
  93. .el-tag {
  94. display: none;
  95. }
  96. }
  97. }
  98. .el-menu-item,
  99. .el-sub-menu {
  100. text-align: left;
  101. }
  102. .el-menu--collapse {
  103. border-right: 0;
  104. .el-sub-menu__icon-arrow {
  105. right: 10px;
  106. margin-top: -3px;
  107. }
  108. }
  109. }
  110. }
  111. :deep() {
  112. .el-scrollbar__wrap {
  113. overflow-x: hidden;
  114. }
  115. .el-menu-item,
  116. .el-sub-menu__title {
  117. height: $base-menu-item-height;
  118. overflow: hidden;
  119. line-height: $base-menu-item-height;
  120. text-overflow: ellipsis;
  121. white-space: nowrap;
  122. vertical-align: middle;
  123. i {
  124. color: inherit;
  125. }
  126. }
  127. .el-menu-item {
  128. @include active;
  129. }
  130. }
  131. }
  132. </style>
  133. <!--由于element-plus
  134. bug使用popper-append-to-body=false会导致多级路由无法显示,故所有菜单必须生成至body下,样式必须放到body下-->
  135. <style lang="scss">
  136. @mixin menuActiveHover {
  137. &:hover,
  138. &.is-active {
  139. i {
  140. color: var(--el-color-white);
  141. }
  142. color: var(--el-color-white);
  143. background: var(--el-color-primary);
  144. .el-sub-menu__title {
  145. i {
  146. color: var(--el-color-white);
  147. }
  148. color: var(--el-color-white);
  149. background: var(--el-color-primary);
  150. }
  151. }
  152. }
  153. .el-menu {
  154. border-right: 0;
  155. }
  156. .el-popper {
  157. .el-menu--vertical {
  158. .el-menu-item,
  159. .el-sub-menu {
  160. height: $base-menu-item-height;
  161. line-height: $base-menu-item-height;
  162. text-overflow: ellipsis;
  163. white-space: nowrap;
  164. vertical-align: middle;
  165. @include menuActiveHover;
  166. i {
  167. color: inherit;
  168. }
  169. .el-sub-menu__title {
  170. height: $base-menu-item-height;
  171. line-height: $base-menu-item-height;
  172. text-overflow: ellipsis;
  173. white-space: nowrap;
  174. vertical-align: middle;
  175. @include menuActiveHover;
  176. }
  177. }
  178. }
  179. }
  180. </style>