Blame view

src/components/mew-menu/menu.vue 5.38 KB
b9851cf0   chenhaodong   mew-menu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  <template>
      <ul :class="classes" :style="styles"><slot></slot></ul>
  </template>
  <script>
      import { oneOf, findComponentsDownward, findComponentsUpward } from '../../utils/assist';
      import Emitter from '../../mixins/emitter';
  
      const prefixCls = 'ivu-menu';
  
      export default {
          name: 'Menu',
          mixins: [ Emitter ],
          props: {
              mode: {
                  validator (value) {
                      return oneOf(value, ['horizontal', 'vertical']);
                  },
                  default: 'vertical'
              },
              theme: {
                  validator (value) {
                      return oneOf(value, ['light', 'dark', 'primary']);
                  },
                  default: 'light'
              },
              activeName: {
                  type: [String, Number]
              },
              openNames: {
                  type: Array,
                  default () {
                      return [];
                  }
              },
              accordion: {
                  type: Boolean,
                  default: false
              },
              width: {
                  type: String,
                  default: '240px'
              }
          },
          data () {
              return {
                  currentActiveName: this.activeName,
                  openedNames: []
              };
          },
          computed: {
              classes () {
                  let theme = this.theme;
                  if (this.mode === 'vertical' && this.theme === 'primary') theme = 'light';
  
                  return [
                      `${prefixCls}`,
                      `${prefixCls}-${theme}`,
                      {
                          [`${prefixCls}-${this.mode}`]: this.mode
                      }
                  ];
              },
              styles () {
                  let style = {};
  
                  if (this.mode === 'vertical') style.width = this.width;
  
                  return style;
              }
          },
          methods: {
              updateActiveName () {
                  if (this.currentActiveName === undefined) {
                      this.currentActiveName = -1;
                  }
                  this.broadcast('Submenu', 'on-update-active-name', false);
                  this.broadcast('MenuItem', 'on-update-active-name', this.currentActiveName);
              },
              updateOpenKeys (name) {
                  let names = [...this.openedNames];
                  const index = names.indexOf(name);
                  if (this.accordion) findComponentsDownward(this, 'Submenu').forEach(item => {
                      item.opened = false;
                  });
                  if (index >= 0) {
                      let currentSubmenu = null;
                      findComponentsDownward(this, 'Submenu').forEach(item => {
                          if (item.name === name) {
                              currentSubmenu = item;
                              item.opened = false;
                          }
                      });
                      findComponentsUpward(currentSubmenu, 'Submenu').forEach(item => {
                          item.opened = true;
                      });
                      findComponentsDownward(currentSubmenu, 'Submenu').forEach(item => {
                          item.opened = false;
                      });
                  } else {
                      if (this.accordion) {
                          let currentSubmenu = null;
                          findComponentsDownward(this, 'Submenu').forEach(item => {
                              if (item.name === name) {
                                  currentSubmenu = item;
                                  item.opened = true;
                              }
                          });
                          findComponentsUpward(currentSubmenu, 'Submenu').forEach(item => {
                              item.opened = true;
                          });
                      } else {
                          findComponentsDownward(this, 'Submenu').forEach(item => {
                              if (item.name === name) item.opened = true;
                          });
                      }
                  }
                  let openedNames = findComponentsDownward(this, 'Submenu').filter(item => item.opened).map(item => item.name);
                  this.openedNames = [...openedNames];
                  this.$emit('on-open-change', openedNames);
              },
              updateOpened () {
                  const items = findComponentsDownward(this, 'Submenu');
  
                  if (items.length) {
                      items.forEach(item => {
                          if (this.openedNames.indexOf(item.name) > -1) item.opened = true;
                          else item.opened = false;
                      });
                  }
              },
              handleEmitSelectEvent (name) {
                  this.$emit('on-select', name);
              }
          },
          mounted () {
              this.openedNames = [...this.openNames];
              this.updateOpened();
              this.$nextTick(() => this.updateActiveName());
              this.$on('on-menu-item-select', (name) => {
                  this.currentActiveName = name;
                  this.$emit('on-select', name);
              });
          },
          watch: {
              openNames (names) {
                  this.openedNames = names;
              },
              activeName (val) {
                  this.currentActiveName = val;
              },
              currentActiveName () {
                  this.updateActiveName();
              }
          }
      };
  </script>