index.render.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import Menu from 'ant-design-vue/es/menu'
  2. import Icon from 'ant-design-vue/es/icon'
  3. const { Item, SubMenu } = Menu
  4. export default {
  5. name: 'SMenu',
  6. props: {
  7. menu: {
  8. type: Array,
  9. required: true
  10. },
  11. theme: {
  12. type: String,
  13. required: false,
  14. default: 'dark'
  15. },
  16. mode: {
  17. type: String,
  18. required: false,
  19. default: 'inline'
  20. },
  21. collapsed: {
  22. type: Boolean,
  23. required: false,
  24. default: false
  25. }
  26. },
  27. data () {
  28. return {
  29. openKeys: [],
  30. selectedKeys: [],
  31. cachedOpenKeys: []
  32. }
  33. },
  34. computed: {
  35. rootSubmenuKeys: vm => {
  36. const keys = []
  37. vm.menu.forEach(item => keys.push(item.path))
  38. return keys
  39. }
  40. },
  41. created () {
  42. this.updateMenu()
  43. },
  44. watch: {
  45. collapsed (val) {
  46. if (val) {
  47. this.cachedOpenKeys = this.openKeys.concat()
  48. this.openKeys = []
  49. } else {
  50. this.openKeys = this.cachedOpenKeys
  51. }
  52. },
  53. $route: function () {
  54. this.updateMenu()
  55. }
  56. },
  57. methods: {
  58. renderIcon: function (h, icon) {
  59. if (icon === 'none' || icon === undefined) {
  60. return null
  61. }
  62. const props = {}
  63. typeof (icon) === 'object' ? props.component = icon : props.type = icon
  64. return h(Icon, { props: { ...props } })
  65. },
  66. renderMenuItem: function (h, menu, pIndex, index) {
  67. const target = menu.meta.target || null
  68. return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index }, [
  69. h('router-link', { attrs: { to: { name: menu.name }, target: target } }, [
  70. this.renderIcon(h, menu.meta.icon),
  71. h('span', [menu.meta.title])
  72. ])
  73. ])
  74. },
  75. renderSubMenu: function (h, menu, pIndex, index) {
  76. const this2_ = this
  77. const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])]
  78. const itemArr = []
  79. const pIndex_ = pIndex + '_' + index
  80. console.log('menu', menu)
  81. if (!menu.hideChildrenInMenu) {
  82. menu.children.forEach(function (item, i) {
  83. itemArr.push(this2_.renderItem(h, item, pIndex_, i))
  84. })
  85. }
  86. return h(SubMenu, { key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index }, subItem.concat(itemArr))
  87. },
  88. renderItem: function (h, menu, pIndex, index) {
  89. if (!menu.hidden) {
  90. return menu.children && !menu.hideChildrenInMenu
  91. ? this.renderSubMenu(h, menu, pIndex, index)
  92. : this.renderMenuItem(h, menu, pIndex, index)
  93. }
  94. },
  95. renderMenu: function (h, menuTree) {
  96. const this2_ = this
  97. const menuArr = []
  98. menuTree.forEach(function (menu, i) {
  99. if (!menu.hidden) {
  100. menuArr.push(this2_.renderItem(h, menu, '0', i))
  101. }
  102. })
  103. return menuArr
  104. },
  105. onOpenChange (openKeys) {
  106. const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
  107. if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
  108. this.openKeys = openKeys
  109. } else {
  110. this.openKeys = latestOpenKey ? [latestOpenKey] : []
  111. }
  112. },
  113. updateMenu () {
  114. const routes = this.$route.matched.concat()
  115. if (routes.length >= 4 && this.$route.meta.hidden) {
  116. routes.pop()
  117. this.selectedKeys = [routes[2].path]
  118. } else {
  119. this.selectedKeys = [routes.pop().path]
  120. }
  121. const openKeys = []
  122. if (this.mode === 'inline') {
  123. routes.forEach(item => {
  124. openKeys.push(item.path)
  125. })
  126. }
  127. this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
  128. }
  129. },
  130. render (h) {
  131. return h(
  132. Menu,
  133. {
  134. props: {
  135. theme: this.$props.theme,
  136. mode: this.$props.mode,
  137. openKeys: this.openKeys,
  138. selectedKeys: this.selectedKeys
  139. },
  140. on: {
  141. openChange: this.onOpenChange,
  142. select: obj => {
  143. this.selectedKeys = obj.selectedKeys
  144. this.$emit('select', obj)
  145. }
  146. }
  147. },
  148. this.renderMenu(h, this.menu)
  149. )
  150. }
  151. }