MenuContent.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <ul class="menu-content"
  3. :style="{width: lang.lang === 'en' ? '160px' : '120px'}"
  4. >
  5. <template v-for="(menu, index) in menus" :key="menu.text || index">
  6. <li
  7. v-if="!menu.hide"
  8. class="menu-item"
  9. @click.stop="handleClickMenuItem(menu)"
  10. :class="{'divider': menu.divider, 'disable': menu.disable}"
  11. >
  12. <div
  13. class="menu-item-content"
  14. :class="{
  15. 'has-children': menu.children,
  16. 'has-handler': menu.handler,
  17. }"
  18. v-if="!menu.divider"
  19. >
  20. <span class="text">{{menu.text}}</span>
  21. <span class="sub-text" v-if="menu.subText && !menu.children">{{menu.subText}}</span>
  22. <menu-content
  23. class="sub-menu"
  24. :menus="menu.children"
  25. v-if="menu.children && menu.children.length"
  26. :handleClickMenuItem="handleClickMenuItem"
  27. />
  28. </div>
  29. </li>
  30. </template>
  31. </ul>
  32. </template>
  33. <script lang="ts" setup>
  34. import type { ContextmenuItem } from './types'
  35. import { lang } from '@/main'
  36. defineProps<{
  37. menus: ContextmenuItem[]
  38. handleClickMenuItem: (item: ContextmenuItem) => void
  39. }>()
  40. </script>
  41. <style lang="scss" scoped>
  42. $menuWidth: 180px;
  43. $menuHeight: 30px;
  44. $subMenuWidth: 120px;
  45. .menu-content {
  46. width: $menuWidth;
  47. padding: 8px;
  48. // background: #fff;
  49. background: #fff;
  50. box-shadow: $boxShadow;
  51. border-radius: 10px;
  52. list-style: none;
  53. margin: 0;
  54. }
  55. .menu-item {
  56. // padding: 0 20px;
  57. color: #555;
  58. font-size: 14px;
  59. transition: all $transitionDelayFast;
  60. white-space: nowrap;
  61. height: 40px;
  62. line-height: 40px;
  63. // background-color: #fff;
  64. background-color: #fff;
  65. cursor: pointer;
  66. border-radius: 10px;
  67. &:not(.disable):hover > .menu-item-content > .sub-menu {
  68. display: block;
  69. }
  70. &:not(.disable):hover > .has-children.has-handler::after {
  71. transform: scale(1);
  72. }
  73. &:hover:not(.disable) {
  74. // background-color: rgba($color: $themeColor, $alpha: .2);
  75. background-color: rgba($color: #ff9300, $alpha: .2);
  76. }
  77. &.divider {
  78. height: 1px;
  79. overflow: hidden;
  80. margin: 5px;
  81. background-color: #e5e5e5;
  82. line-height: 0;
  83. padding: 0;
  84. }
  85. &.disable {
  86. color: #b1b1b1;
  87. cursor: no-drop;
  88. }
  89. }
  90. .menu-item-content {
  91. display: flex;
  92. align-items: center;
  93. // justify-content: space-between;
  94. justify-content: center;
  95. position: relative;
  96. &.has-children::before {
  97. content: '';
  98. display: inline-block;
  99. width: 8px;
  100. height: 8px;
  101. border-width: 1px;
  102. border-style: solid;
  103. border-color: #666 #666 transparent transparent;
  104. position: absolute;
  105. right: 0;
  106. top: 50%;
  107. transform: translateY(-50%) rotate(45deg);
  108. }
  109. &.has-children.has-handler::after {
  110. content: '';
  111. display: inline-block;
  112. width: 1px;
  113. height: 24px;
  114. background-color: rgba($color: #fff, $alpha: .3);
  115. position: absolute;
  116. right: 18px;
  117. top: 3px;
  118. transform: scale(0);
  119. transition: transform $transitionDelay;
  120. }
  121. .sub-text {
  122. opacity: 0.6;
  123. }
  124. .sub-menu {
  125. width: $subMenuWidth;
  126. position: absolute;
  127. display: none;
  128. left: 112%;
  129. top: -6px;
  130. }
  131. }
  132. </style>