index.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <div class="vab-header">
  3. <div class="vab-main">
  4. <el-row :gutter="20">
  5. <el-col :span="6">
  6. <vab-logo />
  7. </el-col>
  8. <el-col :span="18">
  9. <div class="right-panel">
  10. <el-menu
  11. v-if="'horizontal' === layout"
  12. :active-text-color="variables['menu-color-active']"
  13. :background-color="variables['menu-background']"
  14. :default-active="activeMenu"
  15. menu-trigger="hover"
  16. mode="horizontal"
  17. :text-color="variables['menu-color']">
  18. <template v-for="(route, index) in handleRoutes">
  19. <vab-menu
  20. v-if="route.meta && !route.meta.hidden"
  21. :key="index + route.name"
  22. :item="route"
  23. :layout="layout" />
  24. </template>
  25. </el-menu>
  26. <vab-error-log />
  27. <vab-full-screen />
  28. <vab-language />
  29. <vab-refresh />
  30. <vab-avatar />
  31. </div>
  32. </el-col>
  33. </el-row>
  34. </div>
  35. </div>
  36. </template>
  37. <script>
  38. import variables from '@/vab/styles/variables/variables.scss'
  39. import { mapGetters } from 'vuex'
  40. import { handleActivePath, handleMatched } from '@/utils/routes'
  41. export default {
  42. name: 'VabHeader',
  43. props: {
  44. layout: {
  45. type: String,
  46. default: 'horizontal',
  47. },
  48. },
  49. data() {
  50. return {
  51. activeMenu: '',
  52. menuTrigger: 'hover',
  53. }
  54. },
  55. computed: {
  56. ...mapGetters({
  57. routes: 'routes/routes',
  58. activeName: 'routes/activeName',
  59. }),
  60. variables() {
  61. return variables
  62. },
  63. handleRoutes() {
  64. return this.routes.flatMap((route) => {
  65. return route.meta && route.meta.levelHidden === true && route.children
  66. ? route.children
  67. : route
  68. })
  69. },
  70. },
  71. watch: {
  72. $route: {
  73. handler(route) {
  74. this.activeMenu = handleActivePath(route)
  75. },
  76. immediate: true,
  77. },
  78. activeName: {
  79. handler(val) {
  80. const matched = handleMatched(this.routes, val)
  81. this.activeMenu = matched[matched.length - 1].path
  82. },
  83. },
  84. },
  85. }
  86. </script>
  87. <style lang="scss" scoped>
  88. .vab-header {
  89. display: flex;
  90. align-items: center;
  91. justify-items: flex-end;
  92. height: $base-top-bar-height;
  93. background: $base-menu-background;
  94. .vab-main {
  95. padding: 0 $base-padding 0 $base-padding;
  96. .right-panel {
  97. display: flex;
  98. align-items: center;
  99. justify-content: flex-end;
  100. height: $base-top-bar-height;
  101. ::v-deep {
  102. > .el-menu--horizontal.el-menu
  103. > .el-submenu
  104. > .el-submenu__title
  105. > .el-submenu__icon-arrow {
  106. float: right;
  107. margin-top: ($base-top-bar-height - 11) / 2 !important;
  108. }
  109. > .el-menu--horizontal.el-menu > .el-menu-item {
  110. .el-tag {
  111. margin-top: $base-top-bar-height / 2 - 7.5 !important;
  112. margin-left: 5px;
  113. }
  114. .vab-dot {
  115. float: right;
  116. margin-top: ($base-top-bar-height - 6) / 2 + 1;
  117. }
  118. @media only screen and (max-width: 1199px) {
  119. .el-tag {
  120. display: none;
  121. }
  122. }
  123. }
  124. .el-menu {
  125. &.el-menu--horizontal {
  126. display: flex;
  127. align-items: center;
  128. justify-content: flex-end;
  129. height: $base-top-bar-height;
  130. border-bottom: 0 solid transparent !important;
  131. .el-menu-item,
  132. .el-submenu__title {
  133. height: $base-top-bar-height/1.3;
  134. padding: 0 $base-padding;
  135. line-height: $base-top-bar-height/1.3;
  136. }
  137. > .el-menu-item,
  138. > .el-submenu {
  139. height: $base-top-bar-height;
  140. line-height: $base-top-bar-height;
  141. .el-submenu__icon-arrow {
  142. float: right;
  143. margin-top: ($base-menu-item-height - 16) / 2;
  144. }
  145. > .el-submenu__title {
  146. display: flex;
  147. align-items: flex-start;
  148. height: $base-top-bar-height;
  149. line-height: $base-top-bar-height;
  150. }
  151. }
  152. }
  153. [class*='ri-'] {
  154. margin-left: 0;
  155. color: rgba($base-color-white, 0.9);
  156. cursor: pointer;
  157. }
  158. .el-submenu,
  159. .el-menu-item {
  160. i {
  161. color: inherit;
  162. }
  163. &.is-active {
  164. border-bottom: 0 solid transparent;
  165. .el-submenu__title {
  166. border-bottom: 0 solid transparent;
  167. }
  168. }
  169. }
  170. .el-menu-item {
  171. &.is-active {
  172. background: $base-color-blue !important;
  173. }
  174. }
  175. }
  176. .user-name {
  177. color: rgba($base-color-white, 0.9);
  178. }
  179. .user-name + i {
  180. color: rgba($base-color-white, 0.9);
  181. }
  182. [class*='ri-'] {
  183. margin-left: $base-margin;
  184. color: rgba($base-color-white, 0.9);
  185. cursor: pointer;
  186. }
  187. button {
  188. svg {
  189. margin-right: 0;
  190. color: rgba($base-color-white, 0.9);
  191. cursor: pointer;
  192. fill: rgba($base-color-white, 0.9);
  193. }
  194. }
  195. }
  196. }
  197. }
  198. }
  199. </style>