sub-menu.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <!--左侧二级菜单树-->
  2. <template>
  3. <div class="sub-menu-main">
  4. <div class="sub-menu-main-content">
  5. <template v-for="(item, index) in $store.state.menu.subMenuRouter">
  6. <div class="sub-menu-item __hover" :class="{active: item.name === $route.name}" @click="toSubMenu(item)">
  7. <div class="sub-menu-item-content">
  8. <div class="icon"/>
  9. {{item.meta.title}}
  10. </div>
  11. </div>
  12. </template>
  13. </div>
  14. </div>
  15. </template>
  16. <script lang="ts">
  17. import {
  18. defineComponent,
  19. computed,
  20. onMounted,
  21. ref,
  22. reactive,
  23. watch,
  24. getCurrentInstance,
  25. ComponentInternalInstance,
  26. toRefs,
  27. nextTick
  28. } from 'vue'
  29. import {useStore} from 'vuex'
  30. import {useRouter, useRoute} from 'vue-router'
  31. export default defineComponent({
  32. name: '',
  33. components: {},
  34. props: {
  35. },
  36. setup() {
  37. const store = useStore();
  38. const router = useRouter();
  39. const route = useRoute();
  40. const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
  41. const state = reactive({})
  42. const toSubMenu = (menu: any) => {
  43. const deep = (r: any) => {
  44. if (r.children?.length > 0) {
  45. deep(r.children[0])
  46. } else {
  47. if (menu.name !== route.name) {
  48. router.push({
  49. path: r.path
  50. })
  51. }
  52. }
  53. }
  54. deep(menu)
  55. }
  56. onMounted(() => {
  57. })
  58. return {
  59. ...toRefs(state),
  60. toSubMenu
  61. }
  62. },
  63. })
  64. </script>
  65. <style scoped lang="scss">
  66. .sub-menu-main {
  67. width: 290px;
  68. height: 918px;
  69. background-image: url("@/assets/images/layout/sub-menu_bg.png");
  70. background-repeat: no-repeat;
  71. background-size: 100% auto;
  72. position: relative;
  73. .sub-menu-main-content {
  74. position: absolute;
  75. display: flex;
  76. flex-direction: column;
  77. top: 172px;
  78. left: 30px;
  79. .sub-menu-item {
  80. width: 185px;
  81. height: 66px;
  82. display: flex;
  83. align-items: center;
  84. position: relative;
  85. &:after {
  86. content: '';
  87. position: absolute;
  88. bottom: 0;
  89. width: 100%;
  90. height: 2px;
  91. background: linear-gradient(270deg, rgba(51,146,255,0) 0%, #3392FF 51%, rgba(51,146,255,0) 100%);
  92. }
  93. &.active {
  94. &:before {
  95. content: '';
  96. position: absolute;
  97. width: 167px;
  98. height: 42px;
  99. background: linear-gradient(90deg, rgba(0,242,254,0) 0%, #00F2FE 39%, #00F2FE 61%, rgba(0,242,254,0) 95%);
  100. z-index: 1;
  101. opacity: 0.4;
  102. }
  103. .sub-menu-item-content {
  104. text-shadow: 0px 2px 4px rgba(0,0,0,0.4);
  105. color: #FFFFFF;
  106. .icon {
  107. background-color: #75fbff;
  108. box-shadow: 0px 0px 20px 3px #75fbff;
  109. }
  110. }
  111. }
  112. .sub-menu-item-content {
  113. height: 42px;
  114. font-size: 20px;
  115. font-family: Microsoft YaHei-Bold, Microsoft YaHei;
  116. font-weight: bold;
  117. color: rgba(255,255,255,0.5);
  118. display: flex;
  119. align-items: center;
  120. padding-left: 30px;
  121. z-index: 2;
  122. .icon {
  123. width: 16px;
  124. height: 16px;
  125. background-color: rgba(42, 187, 255, 0.3);
  126. margin-right: 10px;
  127. transform: rotate(45deg);
  128. }
  129. }
  130. }
  131. }
  132. }
  133. </style>