Blame view

ant-design-vue-jeecg/src/components/menu/index.js 6.23 KB
肖超群 authored
1
2
3
import Menu from 'ant-design-vue/es/menu'
import Icon from 'ant-design-vue/es/icon'
肖超群 authored
4
const {Item, SubMenu} = Menu
肖超群 authored
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

export default {
  name: 'SMenu',
  props: {
    menu: {
      type: Array,
      required: true
    },
    theme: {
      type: String,
      required: false,
      default: 'dark'
    },
    mode: {
      type: String,
      required: false,
      default: 'inline'
    },
    collapsed: {
      type: Boolean,
      required: false,
      default: false
    }
  },
肖超群 authored
29
  data() {
肖超群 authored
30
31
32
33
34
35
36
37
38
39
40
41
42
    return {
      openKeys: [],
      selectedKeys: [],
      cachedOpenKeys: []
    }
  },
  computed: {
    rootSubmenuKeys: vm => {
      const keys = []
      vm.menu.forEach(item => keys.push(item.path))
      return keys
    }
  },
肖超群 authored
43
  mounted() {
肖超群 authored
44
45
46
    this.updateMenu()
  },
  watch: {
肖超群 authored
47
    collapsed(val) {
肖超群 authored
48
49
50
51
52
53
54
55
56
57
58
59
60
      if (val) {
        this.cachedOpenKeys = this.openKeys.concat()
        this.openKeys = []
      } else {
        this.openKeys = this.cachedOpenKeys
      }
    },
    $route: function () {
      this.updateMenu()
    }
  },
  methods: {
    // select menu item
肖超群 authored
61
    onOpenChange(openKeys) {
肖超群 authored
62
63
64
65
66
67
68
69
70
71
72
73
74
75

      // 在水平模式下时执行,并且不再执行后续
      if (this.mode === 'horizontal') {
        this.openKeys = openKeys
        return
      }
      // 非水平模式时
      const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
      if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
        this.openKeys = openKeys
      } else {
        this.openKeys = latestOpenKey ? [latestOpenKey] : []
      }
    },
肖超群 authored
76
    updateMenu() {
77
78
79
      // 解决三级菜单缓存及路由问题 start
      const routes = this.$route.meta['matched'] // 新修改,展开菜单问题
      const { hidden, selectedKeys } = this.$route.meta
肖超群 authored
80
      if (routes.length >= 3 && hidden) {
81
82
          routes.pop()
          this.selectedKeys = selectedKeys
肖超群 authored
83
      } else {
84
          this.selectedKeys = [routes.pop().path]
肖超群 authored
85
86
87
      }
      let openKeys = []
      if (this.mode === 'inline') {
88
89
90
          routes.forEach(item => {
            openKeys.push(item.path)
          })
肖超群 authored
91
      }
92
      // 解决三级菜单缓存及路由问题 end
肖超群 authored
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

      // update-begin-author:sunjianlei date:20210409 for: 修复动态功能测试菜单、带参数菜单标题错误、展开错误的问题
      // 包含冒号的是动态菜单
      if (this.selectedKeys[0].includes(':')) {
        let selectedKey = this.$route.fullPath
        this.selectedKeys = [selectedKey]
        let newOpenKeys = []
        this.fullOpenKeys(this.menu, selectedKey, newOpenKeys)
        if (newOpenKeys.length > 0) {
          openKeys = newOpenKeys.reverse()
        }
      }
      // update-end-author:sunjianlei date:20210409 for: 修复动态功能测试菜单、带参数菜单标题错误、展开错误的问题

      //update-begin-author:taoyan date:20190510 for:online表单菜单点击展开的一级目录不对
肖超群 authored
108
      if (!this.selectedKeys || this.selectedKeys[0].indexOf(":") < 0) {
肖超群 authored
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
        this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
      }
      //update-end-author:taoyan date:20190510 for:online表单菜单点击展开的一级目录不对
    },
    // update-begin-author:sunjianlei date:20210409 for: 修复动态功能测试菜单、带参数菜单标题错误、展开错误的问题
    // 递归查找当前选中的菜单和父级菜单,填充openKeys
    fullOpenKeys(menus, selectedKey, openKeys) {
      for (let item of menus) {
        if (item.path === selectedKey) {
          openKeys.push(item.path)
          this.$emit('updateMenuTitle', item)
          return true
        } else if (Array.isArray(item.children)) {
          if (this.fullOpenKeys(item.children, selectedKey, openKeys)) {
            openKeys.push(item.path)
            return true
          }
        }
      }
    },
    // update-end-author:sunjianlei date:20210409 for: 修复动态功能测试菜单、带参数菜单标题错误、展开错误的问题

    // render
肖超群 authored
132
    renderItem(menu) {
肖超群 authored
133
134
135
136
137
      if (!menu.hidden) {
        return menu.children && !menu.alwaysShow ? this.renderSubMenu(menu) : this.renderMenuItem(menu)
      }
      return null
    },
肖超群 authored
138
    renderMenuItem(menu) {
肖超群 authored
139
140
      const target = menu.meta.target || null
      const tag = target && 'a' || 'router-link'
肖超群 authored
141
142
143
      let props = {to: {name: menu.name}}
      if (menu.route && menu.route === '0') {
        props = {to: {path: menu.path}}
肖超群 authored
144
145
      }
肖超群 authored
146
      const attrs = {href: menu.path, target: menu.meta.target}
肖超群 authored
147
148
149
150
151
152

      if (menu.children && menu.alwaysShow) {
        // 把有子菜单的 并且 父菜单是要隐藏子菜单的
        // 都给子菜单增加一个 hidden 属性
        // 用来给刷新页面时, selectedKeys 做控制用
        menu.children.forEach(item => {
肖超群 authored
153
          item.meta = Object.assign(item.meta, {hidden: true})
肖超群 authored
154
155
156
157
        })
      }

      return (
肖超群 authored
158
159
        <Item {...{key: menu.path}}>
          <tag {...{props, attrs}}>
肖超群 authored
160
161
162
163
164
165
            {this.renderIcon(menu.meta.icon)}
            <span>{menu.meta.title}</span>
          </tag>
        </Item>
      )
    },
肖超群 authored
166
    renderSubMenu(menu) {
肖超群 authored
167
168
169
170
171
      const itemArr = []
      if (!menu.alwaysShow) {
        menu.children.forEach(item => itemArr.push(this.renderItem(item)))
      }
      return (
肖超群 authored
172
        <SubMenu {...{key: menu.path}}>
肖超群 authored
173
174
175
176
177
178
179
180
          <span slot="title">
            {this.renderIcon(menu.meta.icon)}
            <span>{menu.meta.title}</span>
          </span>
          {itemArr}
        </SubMenu>
      )
    },
肖超群 authored
181
    renderIcon(icon) {
肖超群 authored
182
183
184
185
186
187
      if (icon === 'none' || icon === undefined) {
        return null
      }
      const props = {}
      typeof (icon) === 'object' ? props.component = icon : props.type = icon
      return (
肖超群 authored
188
        <Icon {...{props}}/>
肖超群 authored
189
190
191
192
      )
    }
  },
肖超群 authored
193
194
  render() {
    const {mode, theme, menu} = this
肖超群 authored
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
    const props = {
      mode: mode,
      theme: theme,
      openKeys: this.openKeys
    }
    const on = {
      select: obj => {
        this.selectedKeys = obj.selectedKeys
        this.$emit('select', obj)
      },
      openChange: this.onOpenChange
    }

    const menuTree = menu.map(item => {
      if (item.hidden) {
        return null
      }
      return this.renderItem(item)
    })
    // {...{ props, on: on }}
    return (
肖超群 authored
216
      <Menu vModel={this.selectedKeys} {...{props, on: on}}>
肖超群 authored
217
218
219
220
221
        {menuTree}
      </Menu>
    )
  }
}