index.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <template>
  2. <ui-editor-menu :menu="items" class="menu global-menu" :class="{ show: !hide }">
  3. <template v-slot="{ raw }">
  4. <MenuItem
  5. :menu="raw"
  6. :activePaths="activePaths"
  7. @select="item => $emit('select', item.name, item)"
  8. />
  9. </template>
  10. <template #attach v-if="logo">
  11. <div class="logo">
  12. <ui-icon :type="logo"></ui-icon>
  13. </div>
  14. </template>
  15. </ui-editor-menu>
  16. </template>
  17. <script lang="ts">
  18. import { defineComponent, computed } from 'vue'
  19. import { router } from '@/router'
  20. import MenuItem from './menu-item.vue'
  21. import type { PropType } from 'vue'
  22. export type Item = {
  23. name: string
  24. title: string
  25. icon: string
  26. children?: Items
  27. }
  28. export type Items = Item[]
  29. // 查找某个菜单的链条
  30. export const findMenuPaths = (
  31. menus: Items,
  32. activeName: Item['name'],
  33. paths: Item['name'][] = []
  34. ): Item['name'][] => {
  35. for (const menu of menus) {
  36. if (menu.name === activeName) {
  37. return [...paths, menu.name]
  38. } else if (menu.children) {
  39. const queryPaths = findMenuPaths(
  40. menu.children,
  41. activeName,
  42. [...paths, menu.name]
  43. )
  44. if (queryPaths.length) {
  45. return queryPaths
  46. }
  47. }
  48. }
  49. return []
  50. }
  51. export default defineComponent({
  52. name: 'slide-menu',
  53. props: {
  54. items: {
  55. type: Array as PropType<Items>,
  56. required: true,
  57. },
  58. active: {
  59. type: String as PropType<Item['name']>
  60. },
  61. hide: { type: Boolean },
  62. logo: { type: String }
  63. },
  64. emits: {
  65. select: (name: Item['name'], item: Item) => true
  66. },
  67. setup(props) {
  68. const activePaths = computed(() =>
  69. props.active ? findMenuPaths(props.items, props.active) : []
  70. )
  71. return {
  72. activePaths,
  73. }
  74. },
  75. components: {
  76. MenuItem
  77. }
  78. })
  79. </script>
  80. <style lang="sass" scoped src="./style.scss"/>
  81. <style lang="scss">
  82. .global-menu {
  83. display: flex;
  84. flex-direction: column;
  85. .ui-editor-menu-item {
  86. position: relative;
  87. }
  88. >div:not(.logo, .menu-close) {
  89. flex: 1;
  90. }
  91. .logo {
  92. flex: none;
  93. width: auto;
  94. height: auto;
  95. }
  96. }
  97. .readonly .menu-item {
  98. cursor: inherit;
  99. pointer-events: none;
  100. color: var(--editor-men-color) !important;
  101. }
  102. </style>