Blame view

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