index.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <template>
  2. <div class="l-flex--col c-page-sidebar">
  3. <div class="l-flex--row center c-page-sidebar__header">
  4. <router-link
  5. tag="img"
  6. class="c-page-sidebar__logo u-pointer"
  7. src="/logo.png"
  8. to="/"
  9. />
  10. </div>
  11. <el-scrollbar
  12. class="l-flex__auto c-page-sidebar__menu"
  13. wrap-class="c-page-sidebar__wrapper"
  14. >
  15. <el-menu
  16. mode="vertical"
  17. :default-active="activeMenu"
  18. text-color="#a5aec7"
  19. active-text-color="#fff"
  20. :unique-opened="false"
  21. :collapse-transition="false"
  22. >
  23. <sidebar-item
  24. v-for="route in routers"
  25. :key="route.path"
  26. :item="route"
  27. />
  28. </el-menu>
  29. </el-scrollbar>
  30. </div>
  31. </template>
  32. <script>
  33. import path from 'path'
  34. import { mapGetters } from 'vuex'
  35. import SidebarItem from './SidebarItem'
  36. function resolve (...args) {
  37. return path.resolve(...args)
  38. }
  39. function filterRoutes (routes, basePath) {
  40. const res = []
  41. routes.forEach(route => {
  42. if (route.hidden) {
  43. return
  44. }
  45. const { meta = {} } = route
  46. const path = basePath ? resolve(basePath, route.path) : route.path
  47. let children = route.children
  48. if (children) {
  49. children = filterRoutes(children, path)
  50. if (!children.length) {
  51. return
  52. }
  53. if (children.length === 1) {
  54. const { path: cpath, meta: cmeta = {} } = children[0]
  55. res.push({ path: resolve(path, cpath), meta: { ...meta, ...cmeta } })
  56. return
  57. }
  58. res.push({ path, meta, children })
  59. } else {
  60. res.push({ path, meta })
  61. }
  62. })
  63. return res
  64. }
  65. export default {
  66. name: 'Sidebar',
  67. components: { SidebarItem },
  68. computed: {
  69. ...mapGetters(['permissionRoutes']),
  70. routers () {
  71. // 暂时只考虑两层
  72. return filterRoutes(this.permissionRoutes)
  73. },
  74. activeMenu () {
  75. const path = this.$route.matched[1]?.path
  76. return path?.replace(/\/$/, '')
  77. }
  78. }
  79. }
  80. </script>
  81. <style lang="scss" scoped>
  82. .c-page-sidebar {
  83. width: 200px;
  84. background-color: #fff;
  85. box-shadow: 1px 0 4px rgba(0, 21, 41, 0.08);
  86. z-index: 9;
  87. &__header {
  88. flex: none;
  89. height: $height--md;
  90. box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
  91. z-index: 9;
  92. }
  93. &__logo {
  94. max-width: 72%;
  95. max-height: 64%;
  96. }
  97. &__menu {
  98. ::v-deep {
  99. .c-page-sidebar__wrapper {
  100. margin-right: -7px !important;
  101. overflow-x: hidden;
  102. scrollbar-width: none;
  103. }
  104. .el-scrollbar__bar {
  105. display: none;
  106. }
  107. .el-menu {
  108. width: 100%;
  109. }
  110. .el-menu-item,
  111. .el-submenu__title {
  112. display: flex;
  113. align-items: center;
  114. }
  115. .nest-menu .el-menu-item {
  116. padding-left: 48px !important;
  117. }
  118. .el-menu-item,
  119. .el-submenu__title,
  120. .el-icon-arrow-down {
  121. font-weight: bold;
  122. }
  123. .el-menu-item.is-active {
  124. color: #fff !important;
  125. background-color: $blue !important;
  126. }
  127. .is-active > .el-submenu__title,
  128. .is-active > .el-submenu__title > .el-icon-arrow-down {
  129. color: $blue !important;
  130. }
  131. .svg-icon {
  132. margin-right: $spacing--xs;
  133. color: inherit;
  134. font-size: $font-size--lg;
  135. }
  136. .sub-el-icon {
  137. width: $font-size--lg;
  138. height: $font-size--lg;
  139. margin-right: $spacing--xs;
  140. color: inherit;
  141. }
  142. }
  143. }
  144. }
  145. @media screen and (min-width: 1600px) {
  146. .c-page-sidebar {
  147. width: 240px;
  148. &__header {
  149. height: $height--2xl;
  150. }
  151. }
  152. }
  153. </style>