index.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <script lang="ts">
  2. import { h, defineComponent, VNode, toRaw } from 'vue'
  3. import { usePermissionsStore } from '/admin/stores/modules/user/permissions'
  4. import MenuItem from './item.vue'
  5. import menus from './menus.vue'
  6. import { useUserStore } from '/admin/stores/modules/user'
  7. import { Menu } from '/admin/types/Menu'
  8. /**
  9. * 递归渲染 Menu 节点
  10. */
  11. function getVNodes(menus: Menu[] | undefined, _subMenuClass: string | undefined): VNode[] {
  12. const vnodes: VNode[] = []
  13. menus?.forEach(menu => {
  14. if (!menu.meta?.hidden) {
  15. let vnode: VNode
  16. const len = menu.children?.length
  17. if (len) {
  18. vnode = h(
  19. MenuItem,
  20. {
  21. subMenuClass: _subMenuClass,
  22. menu,
  23. },
  24. {
  25. default: () => getVNodes(menu.children, 'children-menu'),
  26. },
  27. )
  28. } else {
  29. vnode = h(MenuItem, {
  30. subMenuClass: _subMenuClass,
  31. menu,
  32. })
  33. }
  34. vnodes.push(vnode)
  35. }
  36. })
  37. return vnodes
  38. }
  39. /**
  40. * filter menus
  41. *
  42. * @param menus
  43. */
  44. function filterMenus(menus: Menu[] | undefined): Menu[] {
  45. const newMenus: Menu[] = []
  46. menus?.forEach(m => {
  47. if (m.meta?.hidden) {
  48. return false
  49. }
  50. if (isHasOnlyChild(m) && m.children?.length) {
  51. newMenus.push(
  52. Object.assign({
  53. path: m.children[0].path,
  54. meta: m.children[0].meta,
  55. name: m.name,
  56. }),
  57. )
  58. } else {
  59. newMenus.push(m)
  60. }
  61. })
  62. return newMenus
  63. }
  64. /**
  65. * is has only child
  66. *
  67. * @param menu
  68. */
  69. function isHasOnlyChild(menu: Menu): boolean {
  70. if (menu.children === undefined) {
  71. return true
  72. }
  73. if (menu.children.length > 1 || !menu.children.length) {
  74. return false
  75. }
  76. if (menu.children[0].children?.length) {
  77. return false
  78. }
  79. return true
  80. }
  81. export default defineComponent({
  82. props: {
  83. subMenuClass: {
  84. type: String,
  85. require: true,
  86. },
  87. menuClass: {
  88. type: String,
  89. require: true,
  90. },
  91. },
  92. setup(props, ctx) {
  93. const permissionsStore = usePermissionsStore()
  94. const userStore = useUserStore()
  95. // 后端的 permissions 返回 undefined,则认为该后端无权限系统
  96. const permissions = userStore.getPermissions === undefined ? [] : userStore.getPermissions
  97. const vnodes = getVNodes(filterMenus(permissionsStore.getMenusFrom(permissions)), props.subMenuClass)
  98. return () => {
  99. return h(
  100. menus,
  101. {
  102. class: 'border-none side-menu ' + props.menuClass,
  103. },
  104. {
  105. default: () => vnodes,
  106. },
  107. )
  108. }
  109. },
  110. })
  111. </script>