Blame view

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