SidebarItem.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <template>
  2. <div v-if="!item.hidden">
  3. <template
  4. v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow"
  5. >
  6. <app-link
  7. v-if="onlyOneChild.meta && onlyOneChild.meta.title !== 'ログアウト'"
  8. :to="resolvePath(onlyOneChild.path, onlyOneChild.query)"
  9. >
  10. <el-menu-item
  11. :class="{ 'submenu-title-noDropdown': !isNest }"
  12. :index="resolvePath(onlyOneChild.path)"
  13. >
  14. <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>
  15. <template #title>
  16. <span :title="hasTitle(onlyOneChild.meta.title)" class="menu-title">
  17. {{ onlyOneChild.meta.title }}
  18. </span>
  19. </template>
  20. </el-menu-item>
  21. </app-link>
  22. <el-menu-item
  23. v-else
  24. :class="{ 'submenu-title-noDropdown': !isNest }"
  25. :index="resolvePath(onlyOneChild.path)"
  26. @click="logout"
  27. >
  28. <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>
  29. <template #title>
  30. <span :title="hasTitle(onlyOneChild.meta.title)" class="menu-title">
  31. {{ onlyOneChild.meta.title }}
  32. </span>
  33. </template>
  34. </el-menu-item>
  35. </template>
  36. <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
  37. <template v-if="item.meta" #title>
  38. <svg-icon :icon-class="item.meta && item.meta.icon"/>
  39. <span :title="hasTitle(item.meta.title)" class="menu-title">{{ item.meta.title }}</span>
  40. </template>
  41. <sidebar-item
  42. v-for="(child, index) in item.children"
  43. :key="child.path + index"
  44. :base-path="resolvePath(child.path)"
  45. :is-nest="true"
  46. :item="child"
  47. class="nest-menu"
  48. />
  49. </el-sub-menu>
  50. </div>
  51. </template>
  52. <script setup>
  53. import {isExternal} from '@/utils/validate'
  54. import AppLink from './Link'
  55. import {getNormalPath} from '@/utils/yamada.js'
  56. import { ElMessageBox } from 'element-plus'
  57. import useUserStore from '@/store/modules/user'
  58. import { formatMsg } from "@/utils/yamada.js"
  59. const props = defineProps({
  60. // route object
  61. item: {
  62. type: Object,
  63. required: true
  64. },
  65. isNest: {
  66. type: Boolean,
  67. default: false
  68. },
  69. basePath: {
  70. type: String,
  71. default: ''
  72. }
  73. })
  74. const onlyOneChild = ref({});
  75. const userStore = useUserStore();
  76. function hasOneShowingChild(children = [], parent) {
  77. if (!children) {
  78. children = [];
  79. }
  80. const showingChildren = children.filter(item => {
  81. if (item.hidden) {
  82. return false
  83. }
  84. onlyOneChild.value = item
  85. return true
  86. })
  87. // When there is only one child router, the child router is displayed by default
  88. if (showingChildren.length === 1) {
  89. return true
  90. }
  91. // Show parent if there are no child router to display
  92. if (showingChildren.length === 0) {
  93. onlyOneChild.value = {...parent, path: '', noShowingChildren: true}
  94. return true
  95. }
  96. return false
  97. };
  98. function resolvePath(routePath, routeQuery) {
  99. if (isExternal(routePath)) {
  100. return routePath
  101. }
  102. if (isExternal(props.basePath)) {
  103. return props.basePath
  104. }
  105. if (routeQuery) {
  106. let query = JSON.parse(routeQuery);
  107. return {path: getNormalPath(props.basePath + '/' + routePath), query: query}
  108. }
  109. return getNormalPath(props.basePath + '/' + routePath)
  110. }
  111. function hasTitle(title) {
  112. if (title.length > 5) {
  113. return title;
  114. } else {
  115. return "";
  116. }
  117. }
  118. function logout() {
  119. ElMessageBox.confirm(formatMsg('Q0003'), '確認', {
  120. confirmButtonText: 'はい',
  121. cancelButtonText: 'いいえ',
  122. type: 'warning'
  123. }).then(() => {
  124. userStore.logOut().then(() => {
  125. location.href = '/index';
  126. })
  127. }).catch(() => {
  128. });
  129. }
  130. </script>