Blame view

src/components/tabs/tabs.vue 8.87 KB
871ed4d8   梁灏   init Tabs component
1
  <template>
17f52abf   梁灏   update Tabs
2
3
4
5
6
      <div :class="classes">
          <div :class="[prefixCls + '-bar']">
              <div :class="[prefixCls + '-nav-container']">
                  <div :class="[prefixCls + '-nav-wrap']">
                      <div :class="[prefixCls + '-nav-scroll']">
30510c3d   梁灏   support Tabs
7
                          <div :class="[prefixCls + '-nav']" ref="nav">
17f52abf   梁灏   update Tabs
8
                              <div :class="barClasses" :style="barStyle"></div>
30510c3d   梁灏   support Tabs
9
                              <div :class="tabCls(item)" v-for="(item, index) in navList" @click="handleChange(index)">
17f52abf   梁灏   update Tabs
10
                                  <Icon v-if="item.icon !== ''" :type="item.icon"></Icon>
1f974700   Aresn   Tabs support rend...
11
12
                                  <Render v-if="item.labelType === 'function'" :render="item.label"></Render>
                                  <template v-else>{{ item.label }}</template>
30510c3d   梁灏   support Tabs
13
                                  <Icon v-if="showClose(item)" type="ios-close-empty" @click.native.stop="handleRemove(index)"></Icon>
17f52abf   梁灏   update Tabs
14
15
                              </div>
                          </div>
8e4f708f   梁灏   update Tabs
16
                          <div :class="[prefixCls + '-nav-right']" v-if="showSlot"><slot name="extra"></slot></div>
17f52abf   梁灏   update Tabs
17
18
19
20
21
22
                      </div>
                  </div>
              </div>
          </div>
          <div :class="contentClasses" :style="contentStyle"><slot></slot></div>
      </div>
871ed4d8   梁灏   init Tabs component
23
24
  </template>
  <script>
17f52abf   梁灏   update Tabs
25
      import Icon from '../icon/icon.vue';
55dbf62d   Aresn   update Tabs render
26
      import Render from '../base/render';
17f52abf   梁灏   update Tabs
27
      import { oneOf, getStyle } from '../../utils/assist';
67c9b1c8   梁灏   fixed #591
28
      import Emitter from '../../mixins/emitter';
17f52abf   梁灏   update Tabs
29
30
31
  
      const prefixCls = 'ivu-tabs';
  
871ed4d8   梁灏   init Tabs component
32
      export default {
30510c3d   梁灏   support Tabs
33
          name: 'Tabs',
67c9b1c8   梁灏   fixed #591
34
          mixins: [ Emitter ],
1f974700   Aresn   Tabs support rend...
35
          components: { Icon, Render },
17f52abf   梁灏   update Tabs
36
          props: {
30510c3d   梁灏   support Tabs
37
              value: {
17f52abf   梁灏   update Tabs
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
                  type: [String, Number]
              },
              type: {
                  validator (value) {
                      return oneOf(value, ['line', 'card']);
                  },
                  default: 'line'
              },
              size: {
                  validator (value) {
                      return oneOf(value, ['small', 'default']);
                  },
                  default: 'default'
              },
              animated: {
                  type: Boolean,
                  default: true
              },
              closable: {
                  type: Boolean,
                  default: false
              }
          },
871ed4d8   梁灏   init Tabs component
61
          data () {
17f52abf   梁灏   update Tabs
62
63
64
65
              return {
                  prefixCls: prefixCls,
                  navList: [],
                  barWidth: 0,
30510c3d   梁灏   support Tabs
66
                  barOffset: 0,
c4eb5dcf   H   tabs组件导航区添加右侧slot...
67
                  activeKey: this.value,
8e4f708f   梁灏   update Tabs
68
                  showSlot: false
b0893113   jingsam   :art: add eslint
69
              };
17f52abf   梁灏   update Tabs
70
71
72
73
74
75
76
77
78
79
          },
          computed: {
              classes () {
                  return [
                      `${prefixCls}`,
                      {
                          [`${prefixCls}-card`]: this.type === 'card',
                          [`${prefixCls}-mini`]: this.size === 'small' && this.type === 'line',
                          [`${prefixCls}-no-animation`]: !this.animated
                      }
b0893113   jingsam   :art: add eslint
80
                  ];
17f52abf   梁灏   update Tabs
81
82
83
84
              },
              contentClasses () {
                  return [
                      `${prefixCls}-content`,
77bafb31   梁灏   update Tabs
85
86
87
                      {
                          [`${prefixCls}-content-animated`]: this.animated
                      }
b0893113   jingsam   :art: add eslint
88
                  ];
17f52abf   梁灏   update Tabs
89
90
91
92
              },
              barClasses () {
                  return [
                      `${prefixCls}-ink-bar`,
77bafb31   梁灏   update Tabs
93
94
95
                      {
                          [`${prefixCls}-ink-bar-animated`]: this.animated
                      }
b0893113   jingsam   :art: add eslint
96
                  ];
17f52abf   梁灏   update Tabs
97
98
              },
              contentStyle () {
30510c3d   梁灏   support Tabs
99
                  const x = this.navList.findIndex((nav) => nav.name === this.activeKey);
17f52abf   梁灏   update Tabs
100
101
102
103
104
105
                  const p = x === 0 ? '0%' : `-${x}00%`;
  
                  let style = {};
                  if (x > -1) {
                      style = {
                          transform: `translateX(${p}) translateZ(0px)`
b0893113   jingsam   :art: add eslint
106
                      };
17f52abf   梁灏   update Tabs
107
108
109
110
111
112
                  }
                  return style;
              },
              barStyle () {
                  let style = {
                      display: 'none',
77bafb31   梁灏   update Tabs
113
                      width: `${this.barWidth}px`
17f52abf   梁灏   update Tabs
114
115
                  };
                  if (this.type === 'line') style.display = 'block';
77bafb31   梁灏   update Tabs
116
117
118
119
120
                  if (this.animated) {
                      style.transform = `translate3d(${this.barOffset}px, 0px, 0px)`;
                  } else {
                      style.left = `${this.barOffset}px`;
                  }
17f52abf   梁灏   update Tabs
121
122
123
124
125
126
127
128
129
130
131
132
  
                  return style;
              }
          },
          methods: {
              getTabs () {
                  return this.$children.filter(item => item.$options.name === 'TabPane');
              },
              updateNav () {
                  this.navList = [];
                  this.getTabs().forEach((pane, index) => {
                      this.navList.push({
1f974700   Aresn   Tabs support rend...
133
                          labelType: typeof pane.label,
17f52abf   梁灏   update Tabs
134
135
                          label: pane.label,
                          icon: pane.icon || '',
30510c3d   梁灏   support Tabs
136
                          name: pane.currentName || index,
7a737482   梁灏   fixed #206
137
138
                          disabled: pane.disabled,
                          closable: pane.closable
17f52abf   梁灏   update Tabs
139
                      });
30510c3d   梁灏   support Tabs
140
                      if (!pane.currentName) pane.currentName = index;
17f52abf   梁灏   update Tabs
141
                      if (index === 0) {
30510c3d   梁灏   support Tabs
142
                          if (!this.activeKey) this.activeKey = pane.currentName || index;
17f52abf   梁灏   update Tabs
143
144
                      }
                  });
77bafb31   梁灏   update Tabs
145
                  this.updateStatus();
17f52abf   梁灏   update Tabs
146
147
148
149
                  this.updateBar();
              },
              updateBar () {
                  this.$nextTick(() => {
30510c3d   梁灏   support Tabs
150
151
                      const index = this.navList.findIndex((nav) => nav.name === this.activeKey);
                      const prevTabs = this.$refs.nav.querySelectorAll(`.${prefixCls}-tab`);
17f52abf   梁灏   update Tabs
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
                      const tab = prevTabs[index];
                      this.barWidth = parseFloat(getStyle(tab, 'width'));
  
                      if (index > 0) {
                          let offset = 0;
                          const gutter = this.size === 'small' ? 0 : 16;
                          for (let i = 0; i < index; i++) {
                              offset += parseFloat(getStyle(prevTabs[i], 'width')) + gutter;
                          }
  
                          this.barOffset = offset;
                      } else {
                          this.barOffset = 0;
                      }
                  });
              },
77bafb31   梁灏   update Tabs
168
169
              updateStatus () {
                  const tabs = this.getTabs();
30510c3d   梁灏   support Tabs
170
                  tabs.forEach(tab => tab.show = (tab.currentName === this.activeKey) || this.animated);
77bafb31   梁灏   update Tabs
171
              },
17f52abf   梁灏   update Tabs
172
173
174
175
176
              tabCls (item) {
                  return [
                      `${prefixCls}-tab`,
                      {
                          [`${prefixCls}-tab-disabled`]: item.disabled,
30510c3d   梁灏   support Tabs
177
                          [`${prefixCls}-tab-active`]: item.name === this.activeKey
17f52abf   梁灏   update Tabs
178
                      }
b0893113   jingsam   :art: add eslint
179
                  ];
17f52abf   梁灏   update Tabs
180
181
182
183
              },
              handleChange (index) {
                  const nav = this.navList[index];
                  if (nav.disabled) return;
30510c3d   梁灏   support Tabs
184
185
186
                  this.activeKey = nav.name;
                  this.$emit('input', nav.name);
                  this.$emit('on-click', nav.name);
17f52abf   梁灏   update Tabs
187
188
189
190
              },
              handleRemove (index) {
                  const tabs = this.getTabs();
                  const tab = tabs[index];
087ad37d   梁灏   update Tabs
191
                  tab.$destroy();
17f52abf   梁灏   update Tabs
192
  
30510c3d   梁灏   support Tabs
193
                  if (tab.currentName === this.activeKey) {
17f52abf   梁灏   update Tabs
194
195
196
197
198
199
200
201
                      const newTabs = this.getTabs();
                      let activeKey = -1;
  
                      if (newTabs.length) {
                          const leftNoDisabledTabs = tabs.filter((item, itemIndex) => !item.disabled && itemIndex < index);
                          const rightNoDisabledTabs = tabs.filter((item, itemIndex) => !item.disabled && itemIndex > index);
  
                          if (rightNoDisabledTabs.length) {
30510c3d   梁灏   support Tabs
202
                              activeKey = rightNoDisabledTabs[0].currentName;
17f52abf   梁灏   update Tabs
203
                          } else if (leftNoDisabledTabs.length) {
30510c3d   梁灏   support Tabs
204
                              activeKey = leftNoDisabledTabs[leftNoDisabledTabs.length - 1].currentName;
17f52abf   梁灏   update Tabs
205
                          } else {
30510c3d   梁灏   support Tabs
206
                              activeKey = newTabs[0].currentName;
17f52abf   梁灏   update Tabs
207
208
209
                          }
                      }
                      this.activeKey = activeKey;
087ad37d   梁灏   update Tabs
210
                      this.$emit('input', activeKey);
17f52abf   梁灏   update Tabs
211
                  }
30510c3d   梁灏   support Tabs
212
                  this.$emit('on-tab-remove', tab.currentName);
17f52abf   梁灏   update Tabs
213
                  this.updateNav();
7a737482   梁灏   fixed #206
214
215
216
217
218
219
220
221
222
223
224
              },
              showClose (item) {
                  if (this.type === 'card') {
                      if (item.closable !== null) {
                          return item.closable;
                      } else {
                          return this.closable;
                      }
                  } else {
                      return false;
                  }
17f52abf   梁灏   update Tabs
225
226
              }
          },
17f52abf   梁灏   update Tabs
227
          watch: {
30510c3d   梁灏   support Tabs
228
229
230
              value (val) {
                  this.activeKey = val;
              },
17f52abf   梁灏   update Tabs
231
232
              activeKey () {
                  this.updateBar();
0c5e01f1   梁灏   fixed #185
233
                  this.updateStatus();
67c9b1c8   梁灏   fixed #591
234
                  this.broadcast('Table', 'on-visible-change', true);
17f52abf   梁灏   update Tabs
235
              }
c4eb5dcf   H   tabs组件导航区添加右侧slot...
236
          },
8e4f708f   梁灏   update Tabs
237
238
          mounted () {
              this.showSlot = this.$slots.extra !== undefined;
17f52abf   梁灏   update Tabs
239
          }
b0893113   jingsam   :art: add eslint
240
241
      };
  </script>