Blame view

src/components/tabs/tabs.vue 7.93 KB
871ed4d8   梁灏   init Tabs component
1
  <template>
17f52abf   梁灏   update Tabs
2
3
4
5
6
7
8
9
10
11
      <div :class="classes">
          <div :class="[prefixCls + '-bar']">
              <div :class="[prefixCls + '-nav-container']">
                  <div :class="[prefixCls + '-nav-wrap']">
                      <div :class="[prefixCls + '-nav-scroll']">
                          <div :class="[prefixCls + '-nav']" v-el:nav>
                              <div :class="barClasses" :style="barStyle"></div>
                              <div :class="tabCls(item)" v-for="item in navList" @click="handleChange($index)">
                                  <Icon v-if="item.icon !== ''" :type="item.icon"></Icon>
                                  {{ item.label }}
7a737482   梁灏   fixed #206
12
                                  <Icon v-if="showClose(item)" type="ios-close-empty" @click.stop="handleRemove($index)"></Icon>
17f52abf   梁灏   update Tabs
13
14
15
16
17
18
19
20
                              </div>
                          </div>
                      </div>
                  </div>
              </div>
          </div>
          <div :class="contentClasses" :style="contentStyle"><slot></slot></div>
      </div>
871ed4d8   梁灏   init Tabs component
21
22
  </template>
  <script>
17f52abf   梁灏   update Tabs
23
24
25
26
27
      import Icon from '../icon/icon.vue';
      import { oneOf, getStyle } from '../../utils/assist';
  
      const prefixCls = 'ivu-tabs';
  
871ed4d8   梁灏   init Tabs component
28
      export default {
17f52abf   梁灏   update Tabs
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
          components: { Icon },
          props: {
              activeKey: {
                  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
55
          data () {
17f52abf   梁灏   update Tabs
56
57
58
59
60
              return {
                  prefixCls: prefixCls,
                  navList: [],
                  barWidth: 0,
                  barOffset: 0
b0893113   jingsam   :art: add eslint
61
              };
17f52abf   梁灏   update Tabs
62
63
64
65
66
67
68
69
70
71
          },
          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
72
                  ];
17f52abf   梁灏   update Tabs
73
74
75
76
              },
              contentClasses () {
                  return [
                      `${prefixCls}-content`,
77bafb31   梁灏   update Tabs
77
78
79
                      {
                          [`${prefixCls}-content-animated`]: this.animated
                      }
b0893113   jingsam   :art: add eslint
80
                  ];
17f52abf   梁灏   update Tabs
81
82
83
84
              },
              barClasses () {
                  return [
                      `${prefixCls}-ink-bar`,
77bafb31   梁灏   update Tabs
85
86
87
                      {
                          [`${prefixCls}-ink-bar-animated`]: this.animated
                      }
b0893113   jingsam   :art: add eslint
88
                  ];
17f52abf   梁灏   update Tabs
89
90
              },
              contentStyle () {
b0893113   jingsam   :art: add eslint
91
                  const x = this.navList.findIndex((nav) => nav.key === this.activeKey);
17f52abf   梁灏   update Tabs
92
93
94
95
96
97
                  const p = x === 0 ? '0%' : `-${x}00%`;
  
                  let style = {};
                  if (x > -1) {
                      style = {
                          transform: `translateX(${p}) translateZ(0px)`
b0893113   jingsam   :art: add eslint
98
                      };
17f52abf   梁灏   update Tabs
99
100
101
102
103
104
                  }
                  return style;
              },
              barStyle () {
                  let style = {
                      display: 'none',
77bafb31   梁灏   update Tabs
105
                      width: `${this.barWidth}px`
17f52abf   梁灏   update Tabs
106
107
                  };
                  if (this.type === 'line') style.display = 'block';
77bafb31   梁灏   update Tabs
108
109
110
111
112
                  if (this.animated) {
                      style.transform = `translate3d(${this.barOffset}px, 0px, 0px)`;
                  } else {
                      style.left = `${this.barOffset}px`;
                  }
17f52abf   梁灏   update Tabs
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  
                  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 || '',
                          key: pane.key || index,
7a737482   梁灏   fixed #206
128
129
                          disabled: pane.disabled,
                          closable: pane.closable
17f52abf   梁灏   update Tabs
130
131
132
133
134
135
                      });
                      if (!pane.key) pane.key = index;
                      if (index === 0) {
                          if (!this.activeKey) this.activeKey = pane.key || index;
                      }
                  });
77bafb31   梁灏   update Tabs
136
                  this.updateStatus();
17f52abf   梁灏   update Tabs
137
138
139
140
                  this.updateBar();
              },
              updateBar () {
                  this.$nextTick(() => {
b0893113   jingsam   :art: add eslint
141
                      const index = this.navList.findIndex((nav) => nav.key === this.activeKey);
17f52abf   梁灏   update Tabs
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
                      const prevTabs = this.$els.nav.querySelectorAll(`.${prefixCls}-tab`);
                      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
159
160
161
162
              updateStatus () {
                  const tabs = this.getTabs();
                  tabs.forEach(tab => tab.show = (tab.key === this.activeKey) || this.animated);
              },
17f52abf   梁灏   update Tabs
163
164
165
166
167
168
169
              tabCls (item) {
                  return [
                      `${prefixCls}-tab`,
                      {
                          [`${prefixCls}-tab-disabled`]: item.disabled,
                          [`${prefixCls}-tab-active`]: item.key === this.activeKey
                      }
b0893113   jingsam   :art: add eslint
170
                  ];
17f52abf   梁灏   update Tabs
171
172
173
174
175
              },
              handleChange (index) {
                  const nav = this.navList[index];
                  if (nav.disabled) return;
                  this.activeKey = nav.key;
17f52abf   梁灏   update Tabs
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
                  this.$emit('on-click', nav.key);
              },
              handleRemove (index) {
                  const tabs = this.getTabs();
                  const tab = tabs[index];
                  tab.$destroy(true);
  
                  if (tab.key === this.activeKey) {
                      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) {
                              activeKey = rightNoDisabledTabs[0].key;
                          } else if (leftNoDisabledTabs.length) {
                              activeKey = leftNoDisabledTabs[leftNoDisabledTabs.length - 1].key;
                          } else {
                              activeKey = newTabs[0].key;
                          }
                      }
                      this.activeKey = activeKey;
                  }
                  this.$emit('on-tab-remove', tab.key);
                  this.updateNav();
7a737482   梁灏   fixed #206
203
204
205
206
207
208
209
210
211
212
213
              },
              showClose (item) {
                  if (this.type === 'card') {
                      if (item.closable !== null) {
                          return item.closable;
                      } else {
                          return this.closable;
                      }
                  } else {
                      return false;
                  }
17f52abf   梁灏   update Tabs
214
215
              }
          },
17f52abf   梁灏   update Tabs
216
217
218
          watch: {
              activeKey () {
                  this.updateBar();
0c5e01f1   梁灏   fixed #185
219
                  this.updateStatus();
17f52abf   梁灏   update Tabs
220
221
              }
          }
b0893113   jingsam   :art: add eslint
222
223
      };
  </script>