MenuItem.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template>
  2. <div v-for="(item , index) in computedMenu"
  3. :key="index"
  4. class="menu-item">
  5. <q-expansion-item v-if="!loading && item.children && item.children.length > 0 && item.show"
  6. :header-style="{height:'40px', borderRadius: '14px'}"
  7. :label="item.title"
  8. :icon="item.icon"
  9. :default-opened="item.open"
  10. class="side-expansion-list">
  11. <div class="expansion-body">
  12. <q-separator dark
  13. size="2px"
  14. vertical
  15. class="vertical-separator" />
  16. <q-list class="list-expansion">
  17. <div v-for="(subItem , i) in item.children"
  18. :key="i">
  19. <menu-item v-if="subItem.children && subItem.children.length > 0"
  20. :items="[subItem]"
  21. @item-selected="itemSelected(item)" />
  22. <q-item v-else
  23. v-ripple
  24. clickable
  25. :to="redirectRoute(subItem)"
  26. exact
  27. @click="itemSelected(subItem)">
  28. <q-tooltip v-if="showChildItemTooltip"
  29. anchor="top middle"
  30. self="bottom middle"
  31. :offset="[10, 10]">
  32. {{ subItem.title }}
  33. </q-tooltip>
  34. <q-item-section class="list-child-section">
  35. <q-item-label lines="1">{{ subItem.title }}</q-item-label>
  36. </q-item-section>
  37. <q-badge v-if="subItem.badge"
  38. class="badge q-py-xs"
  39. align="middle">
  40. {{subItem.badge}}
  41. </q-badge>
  42. <span class="indicator" />
  43. </q-item>
  44. </div>
  45. </q-list>
  46. </div>
  47. </q-expansion-item>
  48. <!-- (item.title === clickedItem.title) || -->
  49. <q-item v-else-if="!loading && !item.children"
  50. v-ripple
  51. clickable
  52. :to="redirectRoute(item)"
  53. exact
  54. @click="itemSelected(item)">
  55. <q-item-section v-if="item.icon"
  56. avatar>
  57. <q-avatar :icon="item.icon"
  58. size="30" />
  59. </q-item-section>
  60. <q-item-section>
  61. {{ item.title }}
  62. </q-item-section>
  63. </q-item>
  64. <q-badge v-if="item.badge"
  65. align="middle">
  66. {{item.badge}}
  67. </q-badge>
  68. <q-skeleton v-if="loading" />
  69. </div>
  70. </template>
  71. <script>
  72. export default {
  73. name: 'MenuItem',
  74. props: {
  75. menuItemsColor: {
  76. type: String,
  77. default: ''
  78. },
  79. menu: {
  80. // ToDO: will be deprecate
  81. type: Array,
  82. default: () => []
  83. },
  84. items: {
  85. type: Array,
  86. default: () => []
  87. },
  88. showChildItemTooltip: {
  89. type: Boolean,
  90. default: false
  91. },
  92. loading: {
  93. type: Boolean,
  94. default: () => {
  95. return false
  96. }
  97. }
  98. },
  99. emits: ['itemSelected', 'update:menu'],
  100. data () {
  101. return {
  102. clickedItem: {
  103. title: ''
  104. },
  105. menuItems: []
  106. }
  107. },
  108. computed: {
  109. computedMenu: {
  110. get () {
  111. if (this.menu.length > 0) {
  112. return this.menu
  113. } else {
  114. return this.items
  115. }
  116. },
  117. set (value) {
  118. this.menuItems = value
  119. this.$emit('update:menu', this.menuItems)
  120. }
  121. },
  122. selectedTopic() {
  123. return this.$store.getters['TripleTitleSet/selectedTopic']
  124. }
  125. },
  126. methods: {
  127. isActive(item) {
  128. return (item.title === this.selectedTopic) || (item.title === this.clickedItem.title)
  129. },
  130. redirectRoute(item) {
  131. if (item.tags) {
  132. return { name: 'Public.Home', query: { 'tags[]': item.tags } }
  133. } else if (item.href) {
  134. return { path: item.href }
  135. } else if (item.route) {
  136. return item.route
  137. } else if (!item.routeName) {
  138. return undefined
  139. }
  140. return { name: item.routeName }
  141. },
  142. itemSelected(item) {
  143. this.clickedItem = item
  144. this.$emit('itemSelected', item)
  145. if (!this.redirectRoute(item)) {
  146. window.location.href = item.externalLink
  147. }
  148. },
  149. inactiveAllItems () {
  150. }
  151. }
  152. }
  153. </script>
  154. <style lang="scss" scoped>
  155. .menu-item {
  156. :deep(.q-expansion-item) {
  157. .q-item {
  158. .q-item__section {
  159. &.q-item__section--avatar {
  160. min-width: 0;
  161. padding-right: 13px;
  162. }
  163. }
  164. }
  165. .q-expansion-item__content {
  166. //padding-left: 15px;
  167. }
  168. }
  169. :deep(.q-item) {
  170. &.q-router-link--exact-active {
  171. background: rgba(91, 122, 95, 0.08);
  172. position: relative;
  173. &:before {
  174. content: ' ';
  175. position: absolute;
  176. left: 0;
  177. top: 0;
  178. width: 6px;
  179. height: 100%;
  180. background: #5B7A5F;
  181. border-radius: 0 5px 5px 0;
  182. }
  183. }
  184. .q-item__section {
  185. &.q-item__section--avatar {
  186. width: 37px;
  187. min-width: 37px;
  188. .q-avatar {
  189. width: 100%;
  190. }
  191. }
  192. }
  193. }
  194. }
  195. </style>