SidebarItem.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <div v-if="!item.hidden">
  3. <template
  4. v-if="
  5. hasOneShowingChild(item.children, item) &&
  6. (!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
  7. !item.alwaysShow
  8. "
  9. >
  10. <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
  11. <el-menu-item
  12. :index="resolvePath(onlyOneChild.path)"
  13. :class="{ 'submenu-title-noDropdown': !isNest }"
  14. >
  15. <i :class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" />
  16. <template #title>
  17. <span>{{ $t(onlyOneChild.meta.title) }}</span>
  18. </template>
  19. </el-menu-item>
  20. </app-link>
  21. </template>
  22. <el-sub-menu
  23. v-else
  24. ref="subMenu"
  25. :index="resolvePath(item.path)"
  26. popper-append-to-body
  27. >
  28. <template #title>
  29. <i :class="item.meta.icon"></i>
  30. <span>{{ $t(item.meta.title) }}</span>
  31. </template>
  32. <sidebar-item
  33. v-for="child in item.children"
  34. :key="child.path"
  35. :is-nest="true"
  36. :item="child"
  37. :base-path="resolvePath(child.path)"
  38. class="nest-menu"
  39. />
  40. </el-sub-menu>
  41. </div>
  42. </template>
  43. <script lang="ts">
  44. import path from "path";
  45. import AppLink from "./Link.vue";
  46. import { defineComponent, PropType, ref } from "vue";
  47. import { RouteRecordRaw } from "vue-router";
  48. import { isUrl } from "/@/utils/is.ts";
  49. export default defineComponent({
  50. name: "SidebarItem",
  51. components: { AppLink },
  52. props: {
  53. item: {
  54. type: Object as PropType<RouteRecordRaw>,
  55. required: true
  56. },
  57. isNest: {
  58. type: Boolean,
  59. default: false
  60. },
  61. basePath: {
  62. type: String,
  63. default: ""
  64. }
  65. },
  66. setup(props) {
  67. const onlyOneChild = ref<RouteRecordRaw>({} as any);
  68. function hasOneShowingChild(
  69. children: RouteRecordRaw[] = [],
  70. parent: RouteRecordRaw
  71. ) {
  72. const showingChildren = children.filter((item: any) => {
  73. if (item.hidden) {
  74. // 不显示hidden属性为true的菜单
  75. return false;
  76. } else {
  77. onlyOneChild.value = item;
  78. return true;
  79. }
  80. });
  81. if (showingChildren.length === 1) {
  82. return true;
  83. }
  84. if (showingChildren.length === 0) {
  85. // @ts-ignore
  86. onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
  87. return true;
  88. }
  89. return false;
  90. }
  91. // const resolvePath = (routePath: string) => {
  92. // return path.resolve(props.basePath, routePath);
  93. // };
  94. function resolvePath(routePath) {
  95. if (isUrl(routePath)) {
  96. return routePath;
  97. }
  98. if (isUrl(this.basePath)) {
  99. return props.basePath;
  100. }
  101. // @ts-ignore
  102. return path.resolve(props.basePath, routePath);
  103. }
  104. return { hasOneShowingChild, resolvePath, onlyOneChild };
  105. }
  106. });
  107. </script>