TheMenu.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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: 'medicinal',
  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. label: '碳排放管理',
  86. icon: renderChildrenIcon({ name: 'menu-carbon-emission' }),
  87. key: '/carbon',
  88. },
  89. ]
  90. },
  91. {
  92. label: () => renderLabel('智慧办公'),
  93. icon: renderIcon({ name: 'menu-work' }),
  94. key: '/work'
  95. },
  96. {
  97. label: () => renderLabel('用户中心'),
  98. icon: renderIcon({ name: 'menu-user' }),
  99. key: '/user',
  100. },
  101. ]
  102. const handleUpdateValue = (key, { url }) => {
  103. if (url) return window.open(url);
  104. if (key.includes('normal')) return;
  105. router.push(key);
  106. }
  107. </script>
  108. <template>
  109. <n-scrollbar style="height: 100%">
  110. <n-menu :options="menuOptions" :icon-size="30" v-model:value="activeMenuKey" @update:value="handleUpdateValue">
  111. </n-menu>
  112. </n-scrollbar>
  113. </template>
  114. <style scoped lang="scss"></style>
  115. <style lang="scss">
  116. @mixin sub-menu-active {
  117. .n-menu-item-content__icon {
  118. .icon-default {
  119. display: none;
  120. }
  121. .icon-active {
  122. display: block;
  123. }
  124. }
  125. .n-menu-item-content-header {
  126. font-weight: bold;
  127. }
  128. }
  129. .n-menu .n-menu-item-content:not(.n-menu-item-content--disabled):hover::before {
  130. border: 1px solid #fff;
  131. background: #FCFDFE;
  132. }
  133. // 子菜单hover
  134. .n-submenu-children {
  135. .n-menu-item-content:hover {
  136. @include sub-menu-active();
  137. }
  138. }
  139. // reset - 选中状态
  140. .n-menu-item-content--selected {
  141. @include sub-menu-active();
  142. &:not(.n-menu-item-content--disabled)::before {
  143. border: 1px solid #fff;
  144. background: #FCFDFE;
  145. }
  146. }
  147. // reset - 选中状态
  148. // .n-menu-item-content--selected {
  149. // font-weight: bold;
  150. // }
  151. // .n-base-icon {
  152. // background: url('@/assets/svgs/menu/arrow.svg') center center no-repeat;
  153. // svg {
  154. // display: none;
  155. // }
  156. // }
  157. </style>