mixMenu.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. mounted () {
  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. // select menu item
  59. onOpenChange (openKeys) {
  60. // 在水平模式下时执行,并且不再执行后续
  61. if (this.mode === 'horizontal') {
  62. this.openKeys = openKeys
  63. }
  64. },
  65. updateMenu () {
  66. const routes = this.$route.matched.concat()
  67. const { hidden } = this.$route.meta
  68. console.log(routes)
  69. if (routes.length >= 3 && hidden) {
  70. routes.pop()
  71. this.selectedKeys = [routes[routes.length - 1].name]
  72. } else {
  73. this.selectedKeys = [routes[1].name]
  74. }
  75. this.$store.commit('SET_ACTIVE_MENU', this.selectedKeys[0])
  76. const openKeys = []
  77. if (this.mode === 'inline') {
  78. routes.forEach(item => {
  79. openKeys.push(item.path)
  80. })
  81. }
  82. this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
  83. },
  84. // render
  85. renderItem (menu) {
  86. if (!menu.hidden) {
  87. return this.renderMenuItem(menu)
  88. }
  89. return null
  90. },
  91. renderMenuItem (menu) {
  92. const target = menu.meta.target || null
  93. const tag = target && 'a' || 'router-link'
  94. const props = { to: { name: menu.name } }
  95. const attrs = { href: menu.path, target: menu.meta.target }
  96. if (menu.children && menu.hideChildrenInMenu) {
  97. // 把有子菜单的 并且 父菜单是要隐藏子菜单的
  98. // 都给子菜单增加一个 hidden 属性
  99. // 用来给刷新页面时, selectedKeys 做控制用
  100. menu.children.forEach(item => {
  101. item.meta = Object.assign(item.meta, { hidden: true })
  102. })
  103. }
  104. return (
  105. <Item {...{ key: menu.name }}>
  106. <tag {...{ props, attrs }}>
  107. {this.renderIcon(menu.meta.icon)}
  108. <span>{menu.meta.title}</span>
  109. </tag>
  110. </Item>
  111. )
  112. },
  113. renderSubMenu (menu) {
  114. const itemArr = []
  115. if (!menu.hideChildrenInMenu) {
  116. menu.children.forEach(item => itemArr.push(this.renderItem(item)))
  117. }
  118. return (
  119. <SubMenu {...{ key: menu.name }}>
  120. <span slot="title">
  121. {this.renderIcon(menu.meta.icon)}
  122. <span>{menu.meta.title}</span>
  123. </span>
  124. {itemArr}
  125. </SubMenu>
  126. )
  127. },
  128. renderIcon (icon) {
  129. if (icon === 'none' || icon === undefined) {
  130. return null
  131. }
  132. const props = {}
  133. typeof (icon) === 'object' ? props.component = icon : props.type = icon
  134. return (
  135. <Icon {... { props } }/>
  136. )
  137. }
  138. },
  139. render () {
  140. const { mode, theme, menu } = this
  141. const props = {
  142. mode: mode,
  143. theme: theme,
  144. openKeys: this.openKeys
  145. }
  146. const on = {
  147. select: obj => {
  148. this.selectedKeys = obj.selectedKeys
  149. this.$store.commit('SET_ACTIVE_MENU', this.selectedKeys[0])
  150. this.$emit('select', obj)
  151. },
  152. openChange: this.onOpenChange
  153. }
  154. const menuTree = menu.map(item => {
  155. if (item.hidden) {
  156. return null
  157. }
  158. return this.renderItem(item)
  159. })
  160. // {...{ props, on: on }}
  161. return (
  162. <Menu vModel={this.selectedKeys} {...{ props, on: on }}>
  163. {menuTree}
  164. </Menu>
  165. )
  166. }
  167. }