SidebarItem.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <template>
  2. <div v-if="!item.hidden">
  3. <template
  4. v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
  5. <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
  6. <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
  7. <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>
  8. <template #title><span class="menu-title"
  9. :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span>
  10. </template>
  11. </el-menu-item>
  12. </app-link>
  13. </template>
  14. <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
  15. <template v-if="item.meta" #title>
  16. <svg-icon :icon-class="item.meta && item.meta.icon"/>
  17. <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
  18. </template>
  19. <sidebar-item
  20. v-for="(child, index) in item.children"
  21. :key="child.path + index"
  22. :is-nest="true"
  23. :item="child"
  24. :base-path="resolvePath(child.path)"
  25. class="nest-menu"
  26. />
  27. </el-sub-menu>
  28. </div>
  29. </template>
  30. <script setup>
  31. import {isExternal} from '@/utils/validate'
  32. import AppLink from './Link'
  33. import {getNormalPath} from '@/utils/ruoyi'
  34. const props = defineProps({
  35. // route object
  36. item: {
  37. type: Object,
  38. required: true
  39. },
  40. isNest: {
  41. type: Boolean,
  42. default: false
  43. },
  44. basePath: {
  45. type: String,
  46. default: ''
  47. }
  48. })
  49. const onlyOneChild = ref({});
  50. function hasOneShowingChild(children = [], parent) {
  51. if (!children) {
  52. children = [];
  53. }
  54. const showingChildren = children.filter(item => {
  55. if (item.hidden) {
  56. return false
  57. } else {
  58. // Temp set(will be used if only has one showing child)
  59. onlyOneChild.value = item
  60. return true
  61. }
  62. })
  63. // When there is only one child router, the child router is displayed by default
  64. if (showingChildren.length === 1) {
  65. return true
  66. }
  67. // Show parent if there are no child router to display
  68. if (showingChildren.length === 0) {
  69. onlyOneChild.value = {...parent, path: '', noShowingChildren: true}
  70. return true
  71. }
  72. return false
  73. };
  74. function resolvePath(routePath, routeQuery) {
  75. if (isExternal(routePath)) {
  76. return routePath
  77. }
  78. if (isExternal(props.basePath)) {
  79. return props.basePath
  80. }
  81. if (routeQuery) {
  82. let query = JSON.parse(routeQuery);
  83. return {path: getNormalPath(props.basePath + '/' + routePath), query: query}
  84. }
  85. return getNormalPath(props.basePath + '/' + routePath)
  86. }
  87. function hasTitle(title) {
  88. if (title.length > 5) {
  89. return title;
  90. } else {
  91. return "";
  92. }
  93. }
  94. </script>
  95. <style lang='scss' scoped>
  96. // .menu{
  97. // display: flex;
  98. // }
  99. </style>