index.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. let 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
  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. return icon === 'none' || icon === undefined ? null
  60. : h(Icon, { props: { type: icon !== undefined ? icon : '' } })
  61. },
  62. renderMenuItem: function (h, menu, pIndex, index) {
  63. return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index },
  64. [
  65. h(
  66. 'router-link',
  67. { attrs: { to: { name: menu.name } } },
  68. [
  69. this.renderIcon(h, menu.meta.icon),
  70. h('span', [ menu.meta.title ])
  71. ]
  72. )
  73. ]
  74. )
  75. },
  76. renderSubMenu: function (h, menu, pIndex, index) {
  77. const this2_ = this;
  78. let subItem = [ h('span',
  79. { slot: 'title' },
  80. [
  81. this.renderIcon(h, menu.meta.icon),
  82. h('span', [ menu.meta.title ])
  83. ]
  84. ) ]
  85. let itemArr = []
  86. let pIndex_ = pIndex + '_' + index
  87. if (!menu.alwaysShow) {
  88. menu.children.forEach(function (item, i) {
  89. itemArr.push(this2_.renderItem(h, item, pIndex_, i))
  90. })
  91. }
  92. return h(
  93. SubMenu,
  94. { key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index },
  95. subItem.concat(itemArr)
  96. )
  97. },
  98. renderItem: function (h, menu, pIndex, index) {
  99. if (!menu.hidden) {
  100. return menu.children && !menu.alwaysShow ? this.renderSubMenu(h, menu, pIndex, index) : this.renderMenuItem(h, menu, pIndex, index)
  101. }
  102. },
  103. renderMenu: function (h, menuTree) {
  104. const this2_ = this
  105. let menuArr = []
  106. menuTree.forEach(function (menu, i) {
  107. if (!menu.hidden) {
  108. menuArr.push(this2_.renderItem(h, menu, '0', i))
  109. }
  110. })
  111. return menuArr
  112. },
  113. onOpenChange (openKeys) {
  114. const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1)
  115. if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
  116. this.openKeys = openKeys
  117. } else {
  118. this.openKeys = latestOpenKey ? [ latestOpenKey ] : []
  119. }
  120. },
  121. updateMenu () {
  122. let routes = this.$route.matched.concat()
  123. if (routes.length >= 4 && this.$route.meta.hidden) {
  124. routes.pop()
  125. this.selectedKeys = [ routes[2].path ]
  126. } else {
  127. this.selectedKeys = [ routes.pop().path ]
  128. }
  129. let openKeys = []
  130. if (this.mode === 'inline') {
  131. routes.forEach((item) => {
  132. openKeys.push(item.path)
  133. })
  134. }
  135. this.collapsed ? this.cachedOpenKeys = openKeys : this.openKeys = openKeys
  136. }
  137. },
  138. render (h) {
  139. return h(
  140. Menu,
  141. {
  142. props: {
  143. theme: this.$props.theme,
  144. mode: this.$props.mode,
  145. openKeys: this.openKeys,
  146. selectedKeys: this.selectedKeys
  147. },
  148. on: {
  149. openChange: this.onOpenChange,
  150. select: (obj) => {
  151. this.selectedKeys = obj.selectedKeys
  152. this.$emit('select', obj)
  153. }
  154. }
  155. }, this.renderMenu(h, this.menu)
  156. )
  157. }
  158. }