TheMenu.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <script setup lang="jsx">
  2. import { h, watch, ref } from 'vue'
  3. import { useRoute, useRouter } from 'vue-router';
  4. import { NMenu, NScrollbar } from 'naive-ui'
  5. import SvgIcon from '@/components/SvgIcon/index.vue'
  6. const route = useRoute();
  7. const router = useRouter();
  8. const activeMenuKey = ref(route.path);
  9. watch(() => route.path, currentPath => {
  10. activeMenuKey.value = currentPath;
  11. })
  12. function renderIcon (props) {
  13. return () => h(SvgIcon, { ...props })
  14. }
  15. function renderChildrenIcon ({ name, size = '20' }) {
  16. return () => (
  17. <div class="flex items-center justify-center">
  18. {renderIcon({ name, size, class: ['icon-default'] })()}
  19. {renderIcon({ name: name + '-active', size, class: ['icon-active', 'hidden'] })()}
  20. </div>
  21. )
  22. }
  23. function renderLabel (val, url) {
  24. return url ? (<a href={ url } target="_blank" class="pl-1">{ val }</a>) : (<span class="">{ val }</span>) ;
  25. }
  26. const menuOptions = [
  27. {
  28. label: () => renderLabel('智慧总控'),
  29. icon: renderIcon({ name: 'menu-control' }),
  30. key: '/'
  31. },
  32. {
  33. label: () => renderLabel('专家问答'),
  34. icon: renderIcon({ name: 'menu-answers' }),
  35. key: '/answer'
  36. },
  37. {
  38. label: () => renderLabel('工艺管控'),
  39. icon: renderIcon({ name: 'menu-analyse' }),
  40. key: '/analyse',
  41. children: [
  42. {
  43. label: '水质报警',
  44. icon: renderChildrenIcon({ name: 'menu-analyse-water' }),
  45. key: '/water-warn',
  46. },
  47. {
  48. label: '生化报警',
  49. icon: renderChildrenIcon({ name: 'menu-analyse-pymol' }),
  50. key: '/pymol-warn',
  51. },
  52. {
  53. label: '预测预警',
  54. icon: renderChildrenIcon({ name: 'menu-analyse-notice' }),
  55. key: '/forecast-warn',
  56. },
  57. {
  58. label: '智能工单',
  59. icon: renderChildrenIcon({ name: 'menu-analyse-order' }),
  60. key: '/work-order',
  61. }
  62. ]
  63. },
  64. {
  65. label: () => renderLabel('成本管控'),
  66. icon: renderIcon({ name: 'menu-cost-control' }),
  67. key: '/control',
  68. children: [
  69. {
  70. label: '智能投药',
  71. icon: renderChildrenIcon({ name: 'menu-cost-drug' }),
  72. key: 'medicate',
  73. },
  74. {
  75. label: '精准曝气',
  76. icon: renderChildrenIcon({ name: 'menu-cost-accurate' }),
  77. key: 'normal-2',
  78. },
  79. {
  80. label: '微生物镜检',
  81. icon: renderChildrenIcon({ name: 'menu-cost-microorganism' }),
  82. key: 'normal-3',
  83. },
  84. ]
  85. },
  86. {
  87. label: () => renderLabel('智慧办公'),
  88. icon: renderIcon({ name: 'menu-work' }),
  89. key: '/work'
  90. },
  91. {
  92. label: () => renderLabel('用户中心'),
  93. icon: renderIcon({ name: 'menu-user' }),
  94. key: '/user',
  95. },
  96. ]
  97. const handleUpdateValue = (key, { url }) => {
  98. if (url) return window.open(url);
  99. if (key.includes('normal')) return;
  100. router.push(key);
  101. }
  102. </script>
  103. <template>
  104. <n-scrollbar style="height: 100%">
  105. <n-menu :options="menuOptions" :icon-size="30" v-model:value="activeMenuKey" @update:value="handleUpdateValue">
  106. </n-menu>
  107. </n-scrollbar>
  108. </template>
  109. <style scoped lang="scss"></style>
  110. <style lang="scss">
  111. @mixin sub-menu-active {
  112. .n-menu-item-content__icon {
  113. .icon-default {
  114. display: none;
  115. }
  116. .icon-active {
  117. display: block;
  118. }
  119. }
  120. .n-menu-item-content-header {
  121. font-weight: bold;
  122. }
  123. }
  124. .n-menu .n-menu-item-content:not(.n-menu-item-content--disabled):hover::before {
  125. border: 1px solid #fff;
  126. background: #FCFDFE;
  127. }
  128. // 子菜单hover
  129. .n-submenu-children {
  130. .n-menu-item-content:hover {
  131. @include sub-menu-active();
  132. }
  133. }
  134. // reset - 选中状态
  135. .n-menu-item-content--selected {
  136. @include sub-menu-active();
  137. &:not(.n-menu-item-content--disabled)::before {
  138. border: 1px solid #fff;
  139. background: #FCFDFE;
  140. }
  141. }
  142. // reset - 选中状态
  143. // .n-menu-item-content--selected {
  144. // font-weight: bold;
  145. // }
  146. // .n-base-icon {
  147. // background: url('@/assets/svgs/menu/arrow.svg') center center no-repeat;
  148. // svg {
  149. // display: none;
  150. // }
  151. // }
  152. </style>