slide-menu.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <div class="slide-menu">
  3. <div
  4. v-for="item in items"
  5. :class="{active: item.name === activeName}"
  6. :key="item.name"
  7. @click="$emit('changeItem', item as any)"
  8. >
  9. <ui-icon :type="item.icon" :tip="item.title" class="icon" />
  10. </div>
  11. </div>
  12. </template>
  13. <script lang="ts" setup>
  14. import { metas, RoutesName, router, getRouteConfig } from '@/router'
  15. import { views, records, floders } from '@/store';
  16. import { computed } from 'vue';
  17. import type { RouteRecordRaw } from '@/router'
  18. export type MenuItem = {
  19. name: RoutesName,
  20. config: RouteRecordRaw,
  21. } & (typeof metas)[keyof typeof metas]
  22. defineProps<{ activeName: RoutesName }>()
  23. defineEmits<{ (e: 'changeItem', item: MenuItem): void }>()
  24. const items = computed(() => {
  25. const items = [
  26. {
  27. name: RoutesName.summaryShow,
  28. config: getRouteConfig(RoutesName.summaryShow),
  29. ...metas[RoutesName.summaryShow]
  30. }
  31. ]
  32. if (views.value.length) {
  33. items.push({
  34. name: RoutesName.viewShow,
  35. config: getRouteConfig(RoutesName.viewShow),
  36. ...metas[RoutesName.viewShow]
  37. })
  38. }
  39. if (records.value.length) {
  40. items.push({
  41. name: RoutesName.recordShow,
  42. config: getRouteConfig(RoutesName.recordShow),
  43. ...metas[RoutesName.recordShow]
  44. })
  45. }
  46. if (floders.value.length) {
  47. items.push({
  48. name: RoutesName.folderShow,
  49. config: getRouteConfig(RoutesName.folderShow),
  50. ...metas[RoutesName.folderShow]
  51. })
  52. }
  53. return items
  54. })
  55. </script>
  56. <style lang="scss" scoped>
  57. .slide-menu {
  58. width: var(--editor-menu-width);
  59. filter: var(--editor-menu-filter);
  60. background-color: var(--editor-menu-back);
  61. position: fixed;
  62. left: var(--editor-menu-left);
  63. top: var(--editor-head-height);
  64. bottom: 0;
  65. z-index: 2000;
  66. overflow: hidden;
  67. backdrop-filter: blur(4px);
  68. transition: all .3s ease;
  69. > div {
  70. height: 70px;
  71. display: flex;
  72. align-items: center;
  73. justify-content: center;
  74. position: relative;
  75. color: rgba(255, 255, 255, 0.6);
  76. transition: color .3s ease;
  77. cursor: pointer;
  78. &::before {
  79. content: '';
  80. position: absolute;
  81. left: 0;
  82. top: 0;
  83. bottom: 0;
  84. width: 0;
  85. background: currentColor;
  86. transition: width .3s ease;
  87. }
  88. &.active,
  89. &:hover {
  90. color: #00C8AF;
  91. }
  92. &.active::before {
  93. width: 4px;
  94. }
  95. .icon {
  96. font-size: 24px;
  97. color: currentColor;
  98. }
  99. }
  100. }
  101. </style>