index.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <script lang="ts" setup>
  2. import { useRoutesStore } from '@/store/modules/routes'
  3. import variables from '@vab/styles/variables/variables.module.scss'
  4. defineProps({
  5. layout: {
  6. type: String,
  7. default: 'horizontal',
  8. },
  9. })
  10. const routesStore = useRoutesStore()
  11. const { getActiveMenu: activeMenu, getRoutes: routes } =
  12. storeToRefs(routesStore)
  13. </script>
  14. <template>
  15. <div class="vab-header">
  16. <div class="vab-main">
  17. <el-row :gutter="20">
  18. <el-col :span="6">
  19. <vab-logo />
  20. </el-col>
  21. <el-col :span="18">
  22. <div class="right-panel">
  23. <el-menu
  24. v-if="'horizontal' === layout"
  25. :active-text-color="variables['menu-color-active']"
  26. :background-color="variables['menu-background']"
  27. :default-active="activeMenu.data"
  28. menu-trigger="hover"
  29. mode="horizontal"
  30. popper-append-to-body
  31. style="width: 100%"
  32. :text-color="variables['menu-color']"
  33. >
  34. <template
  35. v-for="(item, index) in routes.flatMap((route) =>
  36. route['meta'] &&
  37. route['meta']['levelHidden'] &&
  38. route['children']
  39. ? [...route['children']]
  40. : route
  41. )"
  42. >
  43. <vab-menu
  44. v-if="item['meta'] && !item['meta']['hidden']"
  45. :key="index + item['name']"
  46. :item="item"
  47. :layout="layout"
  48. />
  49. </template>
  50. </el-menu>
  51. <vab-error-log />
  52. <vab-lock />
  53. <vab-search />
  54. <vab-notice />
  55. <vab-full-screen />
  56. <vab-language />
  57. <vab-theme />
  58. <vab-refresh />
  59. <vab-avatar />
  60. </div>
  61. </el-col>
  62. </el-row>
  63. </div>
  64. </div>
  65. </template>
  66. <style lang="scss" scoped>
  67. @use 'sass:math';
  68. $base-menu-height: 40px;
  69. .vab-header {
  70. display: flex;
  71. align-items: center;
  72. justify-items: flex-end;
  73. height: $base-header-height;
  74. background: $base-menu-background;
  75. .vab-main {
  76. padding: 0 $base-padding 0 $base-padding;
  77. .right-panel {
  78. display: flex;
  79. align-items: center;
  80. justify-content: flex-end;
  81. height: $base-header-height;
  82. :deep() {
  83. .el-sub-menu__icon-more {
  84. margin-top: #{math.div($base-menu-height - 20, 2)} !important;
  85. margin-right: 20px !important;
  86. }
  87. > .el-menu--horizontal.el-menu {
  88. > .el-sub-menu > .el-sub-menu__title {
  89. padding-right: 0;
  90. > .el-sub-menu__icon-arrow {
  91. position: relative !important;
  92. margin-top: -5px !important;
  93. margin-right: 0;
  94. margin-left: 30px;
  95. }
  96. }
  97. > .el-menu-item {
  98. .el-tag {
  99. position: relative !important;
  100. margin-top: 0 !important;
  101. margin-right: -20px;
  102. margin-left: 25px;
  103. }
  104. .vab-dot {
  105. float: right;
  106. margin-top: #{math.div($base-header-height - 6, 2)} + 1;
  107. }
  108. @media only screen and (max-width: 1199px) {
  109. .el-tag {
  110. display: none;
  111. }
  112. }
  113. }
  114. }
  115. .el-menu {
  116. border: 0 !important;
  117. * {
  118. border: 0 !important;
  119. }
  120. &.el-menu--horizontal {
  121. display: flex;
  122. align-items: center;
  123. justify-content: flex-end;
  124. width: 100%;
  125. height: $base-menu-height;
  126. border: 0 !important;
  127. > .el-menu-item,
  128. > .el-sub-menu {
  129. height: $base-menu-height;
  130. margin-right: 3px;
  131. line-height: $base-menu-height;
  132. border-radius: 3px;
  133. .el-sub-menu__icon-arrow {
  134. float: right;
  135. margin-top: 7px;
  136. }
  137. > .el-sub-menu__title {
  138. display: flex;
  139. align-items: flex-start;
  140. height: $base-menu-height;
  141. line-height: $base-menu-height;
  142. border: 0 !important;
  143. border-radius: 3px;
  144. }
  145. }
  146. }
  147. [class*='ri-'],
  148. .vab-icon {
  149. margin-left: 0;
  150. color: var(--el-color-white);
  151. cursor: pointer;
  152. }
  153. .el-sub-menu {
  154. .vab-icon {
  155. margin-top: 12px !important;
  156. }
  157. }
  158. .el-sub-menu,
  159. .el-menu-item {
  160. i,
  161. .vab-icon {
  162. color: inherit;
  163. }
  164. &.is-active {
  165. border: 0 !important;
  166. .el-sub-menu__title {
  167. border: 0 !important;
  168. }
  169. }
  170. }
  171. .el-menu-item {
  172. &.is-active {
  173. background: var(--el-color-primary) !important;
  174. }
  175. }
  176. }
  177. .user-name {
  178. color: var(--el-color-white);
  179. }
  180. .user-name + i {
  181. color: var(--el-color-white);
  182. }
  183. [class*='ri-'] {
  184. margin-left: $base-margin;
  185. color: var(--el-color-white);
  186. cursor: pointer;
  187. }
  188. button {
  189. svg {
  190. margin-right: 0;
  191. color: var(--el-color-white);
  192. cursor: pointer;
  193. fill: var(--el-color-white);
  194. }
  195. }
  196. }
  197. }
  198. }
  199. }
  200. </style>
  201. <!--由于element-plus
  202. bug使用popper-append-to-body=false会导致多级路由无法显示,故所有菜单必须生成至body下,样式必须放到body下-->
  203. <style lang="scss">
  204. @use 'sass:math';
  205. @mixin menuActiveHover {
  206. &:hover,
  207. &.is-active {
  208. i {
  209. color: var(--el-color-white) !important;
  210. }
  211. color: var(--el-color-white) !important;
  212. background: var(--el-color-primary) !important;
  213. .el-sub-menu__title {
  214. i {
  215. color: var(--el-color-white) !important;
  216. }
  217. color: var(--el-color-white) !important;
  218. background: var(--el-color-primary) !important;
  219. }
  220. }
  221. }
  222. .el-popper {
  223. .el-menu--horizontal {
  224. height: #{math.div($base-header-height, 1.4)};
  225. border-bottom: 0 solid transparent !important;
  226. @media only screen and (max-width: 1199px) {
  227. .el-tag {
  228. display: none;
  229. }
  230. }
  231. .el-tag {
  232. position: absolute;
  233. right: 20px;
  234. margin-top: 0 !important;
  235. }
  236. .vab-dot {
  237. position: absolute;
  238. right: 20px;
  239. margin-top: 0 !important;
  240. }
  241. .el-menu-item,
  242. .el-sub-menu {
  243. height: #{math.div($base-header-height, 1.4)} !important;
  244. line-height: #{math.div($base-header-height, 1.4)} !important;
  245. @include menuActiveHover;
  246. i,
  247. svg {
  248. color: inherit;
  249. }
  250. .el-sub-menu__icon-arrow {
  251. float: right;
  252. }
  253. .el-sub-menu__title {
  254. height: #{math.div($base-header-height, 1.4)} !important;
  255. line-height: #{math.div($base-header-height, 1.4)} !important;
  256. @include menuActiveHover;
  257. }
  258. }
  259. }
  260. }
  261. </style>