SidebarItem.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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
  11. v-if="onlyOneChild.meta"
  12. :to="resolvePath(onlyOneChild.path, onlyOneChild.query)"
  13. >
  14. <el-menu-item
  15. :index="resolvePath(onlyOneChild.path)"
  16. :class="{ 'submenu-title-noDropdown': !isNest }"
  17. >
  18. <item
  19. :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"
  20. :title="onlyOneChild.meta.title"
  21. :indexnum="indexnum"
  22. />
  23. </el-menu-item>
  24. </app-link>
  25. </template>
  26. <el-submenu
  27. v-else
  28. ref="subMenu"
  29. :index="resolvePath(item.path)"
  30. popper-append-to-body
  31. >
  32. <template slot="title">
  33. <item
  34. v-if="item.meta"
  35. :icon="item.meta && item.meta.icon"
  36. :title="item.meta.title"
  37. :indexnum="indexnum"
  38. />
  39. </template>
  40. <sidebar-item
  41. v-for="child in item.children"
  42. :key="child.path"
  43. :is-nest="true"
  44. :item="child"
  45. :base-path="resolvePath(child.path)"
  46. class="nest-menu"
  47. />
  48. </el-submenu>
  49. </div>
  50. </template>
  51. <script>
  52. import { mapGetters } from "vuex";
  53. import path from "path";
  54. import { isExternal } from "@/utils/validate";
  55. import Item from "./Item";
  56. import AppLink from "./Link";
  57. import FixiOSBug from "./FixiOSBug";
  58. export default {
  59. name: "SidebarItem",
  60. components: { Item, AppLink },
  61. mixins: [FixiOSBug],
  62. props: {
  63. // route object
  64. item: {
  65. type: Object,
  66. required: true,
  67. },
  68. isNest: {
  69. type: Boolean,
  70. default: false,
  71. },
  72. basePath: {
  73. type: String,
  74. default: "",
  75. },
  76. },
  77. data() {
  78. this.onlyOneChild = null;
  79. return {};
  80. },
  81. computed: { ...mapGetters(["indexnum"]) },
  82. methods: {
  83. hasOneShowingChild(children = [], parent) {
  84. if (!children) {
  85. children = [];
  86. }
  87. const showingChildren = children.filter((item) => {
  88. if (item.hidden) {
  89. return false;
  90. } else {
  91. // Temp set(will be used if only has one showing child)
  92. this.onlyOneChild = item;
  93. return true;
  94. }
  95. });
  96. // When there is only one child router, the child router is displayed by default
  97. if (showingChildren.length === 1) {
  98. return true;
  99. }
  100. // Show parent if there are no child router to display
  101. if (showingChildren.length === 0) {
  102. this.onlyOneChild = { ...parent, path: "", noShowingChildren: true };
  103. return true;
  104. }
  105. return false;
  106. },
  107. resolvePath(routePath, routeQuery) {
  108. if (isExternal(routePath)) {
  109. return routePath;
  110. }
  111. if (isExternal(this.basePath)) {
  112. return this.basePath;
  113. }
  114. if (routeQuery) {
  115. let query = JSON.parse(routeQuery);
  116. return { path: path.resolve(this.basePath, routePath), query: query };
  117. }
  118. return path.resolve(this.basePath, routePath);
  119. },
  120. },
  121. };
  122. </script>