MenuBar.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. <template>
  2. <el-menu class="hc-aside-menu" :default-active="curKey" :collapse="isCollapse" unique-opened>
  3. <el-menu-item index="home-index" @click="MenuClick({code: 'home-index'})">
  4. <div class="hc-aside-menu-item">
  5. <div class="menu---item">
  6. <HcIcon name="home-3" :fill="curKey === 'home-index'" class="hc-menu-icon"/>
  7. <div class="name">首页</div>
  8. </div>
  9. </div>
  10. </el-menu-item>
  11. <MenuItem :datas="datas" :cur="curKey" :collapse="isCollapse" @change="MenuClick"/>
  12. </el-menu>
  13. </template>
  14. <script setup>
  15. import {ref, watch} from "vue";
  16. import MenuItem from "./MenuItem.vue"
  17. import {getToken} from "~src/api/util/auth";
  18. const props = defineProps({
  19. datas: {
  20. type: Array,
  21. default: () => ([])
  22. },
  23. cur: {
  24. type: String,
  25. default: 'home-index'
  26. },
  27. collapse: {
  28. type: Boolean,
  29. default: false
  30. },
  31. })
  32. //初始变量
  33. const curKey = ref(props.cur);
  34. const isCollapse = ref(props.collapse);
  35. //监听
  36. watch(() => [
  37. props.cur,
  38. props.collapse
  39. ], ([cur, collapse]) => {
  40. curKey.value = cur
  41. isCollapse.value = collapse
  42. })
  43. //事件
  44. const emit = defineEmits(['change'])
  45. const MenuClick = (item) => {
  46. if (item?.code === 'to-archives-url') {
  47. const token = getToken()
  48. //refreshToken, accessToken
  49. window.open(item?.path + '/#/auth?token=' + token,'_blank')
  50. } else {
  51. curKey.value = item?.code || '';
  52. emit('change', item)
  53. }
  54. }
  55. </script>
  56. <style lang="scss">
  57. .hc-aside-menu.el-menu {
  58. --el-menu-bg-color: initial;
  59. --el-menu-text-color: #838791;
  60. --el-menu-active-color: #ffffff;
  61. --el-menu-hover-text-color: var(--el-color-primary);
  62. --el-menu-hover-bg-color: initial;
  63. --el-menu-item-font-size: 16px;
  64. --el-menu-item-height: 48px;
  65. margin-left: -10px;
  66. border-right: 0;
  67. padding: 8px 0;
  68. &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item,
  69. &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item-group__title,
  70. &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
  71. white-space: nowrap;
  72. padding-left: 0;
  73. }
  74. &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
  75. padding-right: 10px;
  76. }
  77. .el-sub-menu__title {
  78. padding: 0;
  79. }
  80. .el-menu-item, .el-sub-menu {
  81. padding: 15px 0 0 30px !important;
  82. min-width: initial;
  83. transition: 0.2s;
  84. .hc-aside-menu-item {
  85. flex: 1;
  86. position: relative;
  87. border-radius: 50px 0 0 50px;
  88. padding: 0 16px;
  89. display: flex;
  90. align-items: center;
  91. transition: 0.2s;
  92. .menu---item {
  93. display: contents;
  94. }
  95. .hc-menu-icon {
  96. font-size: 22px;
  97. margin-right: 10px;
  98. line-height: initial;
  99. }
  100. .name {
  101. flex: 1;
  102. width: 0;
  103. }
  104. .el-badge, .el-badge .el-badge__content {
  105. vertical-align: initial;
  106. }
  107. }
  108. }
  109. .el-sub-menu .el-icon {
  110. display: none;
  111. }
  112. .el-sub-menu .el-icon.hc-icon-i {
  113. position: relative;
  114. display: inline-block;
  115. font-size: 16px;
  116. right: 15px;
  117. top: initial;
  118. height: initial;
  119. width: initial;
  120. margin-top: 0;
  121. vertical-align: initial;
  122. }
  123. .el-sub-menu .el-sub-menu__title .hc-aside-menu-item:hover,
  124. .el-menu-item:not(.is-active) .hc-aside-menu-item:hover {
  125. color: var(--el-color-primary);
  126. }
  127. .el-sub-menu.is-active > .el-sub-menu__title > .hc-aside-menu-item {
  128. color: var(--el-color-primary);
  129. }
  130. .el-menu-item.is-active {
  131. .hc-aside-menu-item {
  132. --radius-size: 20px;
  133. background-color: var(--el-color-primary);
  134. box-shadow: 0 2px 8px 0 var(--hc-shadow-color-5);
  135. &::before, &::after {
  136. content: '';
  137. display: block;
  138. height: var(--radius-size);
  139. width: var(--radius-size);
  140. position: absolute;
  141. background: radial-gradient(
  142. var(--radius-size) at var(--radius-size) 0px,
  143. transparent var(--radius-size),
  144. var(--el-color-primary) var(--radius-size)
  145. );
  146. }
  147. &::before {
  148. right: 0;
  149. transform: scaleX(-1);
  150. top: calc(-1 * var(--radius-size));
  151. z-index: 999;
  152. }
  153. &::after {
  154. right: 0;
  155. bottom: calc(-1 * var(--radius-size));
  156. transform: scale(-1);
  157. z-index: 999;
  158. }
  159. }
  160. }
  161. }
  162. .hc-aside-menu.el-menu--collapse {
  163. margin-left: 0;
  164. width: 120px;
  165. .el-sub-menu__title {
  166. height: inherit;
  167. line-height: initial;
  168. width: 120px;
  169. justify-content: center;
  170. transition: 0.2s;
  171. }
  172. .el-menu-item, .el-sub-menu {
  173. padding: 0 !important;
  174. height: 60px;
  175. line-height: initial;
  176. display: flex;
  177. align-items: center;
  178. justify-content: center;
  179. width: 120px;
  180. transition: 0.2s;
  181. .hc-aside-menu-item {
  182. display: inline-flex;
  183. align-items: center;
  184. justify-content: center;
  185. width: 60px;
  186. height: 60px;
  187. text-align: center;
  188. border-radius: 10px;
  189. padding: 5px;
  190. flex: initial;
  191. transition: 0.2s;
  192. .menu---item {
  193. position: relative;
  194. display: block;
  195. }
  196. .hc-menu-icon {
  197. margin-right: 0;
  198. }
  199. .name {
  200. flex: initial;
  201. width: 100%;
  202. }
  203. .el-badge, .el-badge .el-badge__content {
  204. vertical-align: initial;
  205. }
  206. .el-badge {
  207. position: absolute;
  208. top: -20px;
  209. right: -24px;
  210. }
  211. }
  212. }
  213. .el-sub-menu .el-icon.hc-icon-i {
  214. display: none;
  215. }
  216. .el-menu-item + .el-menu-item,
  217. .el-menu-item + .el-sub-menu,
  218. .el-sub-menu + .el-menu-item,
  219. .el-sub-menu + .el-sub-menu {
  220. margin-top: 24px;
  221. }
  222. .el-sub-menu:not(.is-active):hover,
  223. .el-menu-item:not(.is-active):hover {
  224. .hc-aside-menu-item {
  225. background-color: var(--el-color-primary-light-9);
  226. color: var(--el-color-primary);
  227. }
  228. }
  229. .el-menu-item.is-active, .el-sub-menu.is-active {
  230. .hc-aside-menu-item {
  231. color: #ffffff !important;
  232. background: linear-gradient(90deg,var(--el-color-primary-light-5), var(--el-color-primary) 100%);
  233. box-shadow: 0 2px 8px 0 var(--hc-shadow-color-5);
  234. &::before, &::after {
  235. content: '';
  236. display: none;
  237. }
  238. }
  239. }
  240. }
  241. .aside-menu-popper.el-popper.is-light {
  242. background: initial !important;
  243. border: 0 !important;
  244. }
  245. .aside-menu-popper.el-popper .el-menu--vertical .el-menu {
  246. --el-menu-bg-color: #f1f5f8;
  247. --el-menu-text-color: #838791;
  248. --el-menu-active-color: #ffffff;
  249. --el-menu-hover-bg-color: initial;
  250. --el-menu-item-font-size: 16px;
  251. background-color: #f1f5f8;
  252. color: #838791;
  253. .el-sub-menu__title {
  254. padding: 0;
  255. justify-content: center;
  256. transition: 0.2s;
  257. }
  258. .el-menu-item, .el-sub-menu {
  259. color: inherit;
  260. padding: 0;
  261. transition: 0.2s;
  262. .hc-aside-menu-item {
  263. flex: 1;
  264. position: relative;
  265. padding: 0 16px;
  266. display: flex;
  267. align-items: center;
  268. transition: 0.2s;
  269. .menu---item {
  270. display: contents;
  271. }
  272. .hc-menu-icon {
  273. font-size: 22px;
  274. margin-right: 10px;
  275. line-height: initial;
  276. }
  277. .name {
  278. flex: 1;
  279. width: 0;
  280. }
  281. .el-badge, .el-badge .el-badge__content {
  282. vertical-align: initial;
  283. }
  284. }
  285. &.is-active {
  286. color: white;
  287. }
  288. }
  289. .el-sub-menu .el-icon {
  290. display: none;
  291. }
  292. .el-sub-menu .el-icon.hc-icon-i {
  293. position: relative;
  294. display: inline-block;
  295. font-size: 16px;
  296. right: 10px;
  297. top: initial;
  298. height: initial;
  299. width: initial;
  300. margin-top: 0;
  301. vertical-align: initial;
  302. }
  303. .el-sub-menu:not(.is-active) .el-sub-menu__title:hover {
  304. background-color: var(--el-color-primary-light-9);
  305. color: var(--el-color-primary);
  306. }
  307. .el-menu-item:not(.is-active):hover {
  308. .hc-aside-menu-item {
  309. background-color: var(--el-color-primary-light-9);
  310. color: var(--el-color-primary);
  311. }
  312. }
  313. .el-menu-item.is-active {
  314. .hc-aside-menu-item {
  315. background-color: var(--el-color-primary);
  316. }
  317. }
  318. .el-sub-menu.is-active .el-sub-menu__title {
  319. background-color: var(--el-color-primary-light-9);
  320. color: var(--el-color-primary);
  321. }
  322. }
  323. .aside-menu-popper.el-popper .el-menu--vertical.home-index .el-menu {
  324. --el-menu-bg-color: initial;
  325. --el-menu-text-color: initial;
  326. color: white;
  327. background-color: rgba(255, 255, 255, 0.25);
  328. backdrop-filter: blur(4px);
  329. }
  330. </style>