Blame view

src/components/tabs/tabs.vue 7.54 KB
871ed4d8   梁灏   init Tabs component
1
  <template>
17f52abf   梁灏   update Tabs
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
      <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 }}
                                  <Icon v-if="closable && type === 'card'" type="ios-close-empty" @click.stop="handleRemove($index)"></Icon>
                              </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
128
129
130
131
132
133
134
  
                  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,
                          disabled: pane.disabled
                      });
                      if (!pane.key) pane.key = index;
                      if (index === 0) {
                          if (!this.activeKey) this.activeKey = pane.key || index;
                      }
                  });
77bafb31   梁灏   update Tabs
135
                  this.updateStatus();
17f52abf   梁灏   update Tabs
136
137
138
139
                  this.updateBar();
              },
              updateBar () {
                  this.$nextTick(() => {
b0893113   jingsam   :art: add eslint
140
                      const index = this.navList.findIndex((nav) => nav.key === this.activeKey);
17f52abf   梁灏   update Tabs
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
                      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
158
159
160
161
              updateStatus () {
                  const tabs = this.getTabs();
                  tabs.forEach(tab => tab.show = (tab.key === this.activeKey) || this.animated);
              },
17f52abf   梁灏   update Tabs
162
163
164
165
166
167
168
              tabCls (item) {
                  return [
                      `${prefixCls}-tab`,
                      {
                          [`${prefixCls}-tab-disabled`]: item.disabled,
                          [`${prefixCls}-tab-active`]: item.key === this.activeKey
                      }
b0893113   jingsam   :art: add eslint
169
                  ];
17f52abf   梁灏   update Tabs
170
171
172
173
174
              },
              handleChange (index) {
                  const nav = this.navList[index];
                  if (nav.disabled) return;
                  this.activeKey = nav.key;
77bafb31   梁灏   update Tabs
175
                  this.updateStatus();
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
203
204
                  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();
              }
          },
17f52abf   梁灏   update Tabs
205
206
207
208
209
          watch: {
              activeKey () {
                  this.updateBar();
              }
          }
b0893113   jingsam   :art: add eslint
210
211
      };
  </script>