Commit 30510c3d9e7850fb52691a6f9fdc5a7592002591

Authored by 梁灏
1 parent b2d29401

support Tabs

support Tabs
CHANGE.md
... ... @@ -25,4 +25,6 @@ class 改为了 className
25 25 ### Tree
26 26 废弃 data,改为 value,使用 v-model,key 更名为 name,不能再 template 的prop 上使用 this
27 27 ### Circle
28   -改名为 iCircle
29 28 \ No newline at end of file
  29 +改名为 iCircle
  30 +### Tabs
  31 +废弃 activeKey,改用 value,使用 v-model,key 更名为 name
30 32 \ No newline at end of file
... ...
README.md
... ... @@ -50,7 +50,7 @@
50 50 - [x] Carousel
51 51 - [x] Tree
52 52 - [ ] Menu
53   -- [ ] Tabs
  53 +- [x] Tabs
54 54 - [ ] Dropdown
55 55 - [ ] Page
56 56 - [ ] Breadcrumb
... ...
src/components/tabs/pane.vue
... ... @@ -7,7 +7,7 @@
7 7 export default {
8 8 name: 'TabPane',
9 9 props: {
10   - key: {
  10 + name: {
11 11 type: String
12 12 },
13 13 label: {
... ... @@ -29,7 +29,8 @@
29 29 data () {
30 30 return {
31 31 prefixCls: prefixCls,
32   - show: true
  32 + show: true,
  33 + currentName: this.name
33 34 };
34 35 },
35 36 methods: {
... ... @@ -38,6 +39,10 @@
38 39 }
39 40 },
40 41 watch: {
  42 + name (val) {
  43 + this.currentName = val;
  44 + this.updateNav();
  45 + },
41 46 label () {
42 47 this.updateNav();
43 48 },
... ... @@ -48,7 +53,7 @@
48 53 this.updateNav();
49 54 }
50 55 },
51   - ready () {
  56 + mounted () {
52 57 this.updateNav();
53 58 }
54 59 };
... ...
src/components/tabs/tabs.vue
... ... @@ -4,12 +4,12 @@
4 4 <div :class="[prefixCls + '-nav-container']">
5 5 <div :class="[prefixCls + '-nav-wrap']">
6 6 <div :class="[prefixCls + '-nav-scroll']">
7   - <div :class="[prefixCls + '-nav']" v-el:nav>
  7 + <div :class="[prefixCls + '-nav']" ref="nav">
8 8 <div :class="barClasses" :style="barStyle"></div>
9   - <div :class="tabCls(item)" v-for="item in navList" @click="handleChange($index)">
  9 + <div :class="tabCls(item)" v-for="(item, index) in navList" @click="handleChange(index)">
10 10 <Icon v-if="item.icon !== ''" :type="item.icon"></Icon>
11 11 {{ item.label }}
12   - <Icon v-if="showClose(item)" type="ios-close-empty" @click.stop="handleRemove($index)"></Icon>
  12 + <Icon v-if="showClose(item)" type="ios-close-empty" @click.native.stop="handleRemove(index)"></Icon>
13 13 </div>
14 14 </div>
15 15 </div>
... ... @@ -26,9 +26,10 @@
26 26 const prefixCls = 'ivu-tabs';
27 27  
28 28 export default {
  29 + name: 'Tabs',
29 30 components: { Icon },
30 31 props: {
31   - activeKey: {
  32 + value: {
32 33 type: [String, Number]
33 34 },
34 35 type: {
... ... @@ -57,7 +58,8 @@
57 58 prefixCls: prefixCls,
58 59 navList: [],
59 60 barWidth: 0,
60   - barOffset: 0
  61 + barOffset: 0,
  62 + activeKey: this.value
61 63 };
62 64 },
63 65 computed: {
... ... @@ -88,7 +90,7 @@
88 90 ];
89 91 },
90 92 contentStyle () {
91   - const x = this.navList.findIndex((nav) => nav.key === this.activeKey);
  93 + const x = this.navList.findIndex((nav) => nav.name === this.activeKey);
92 94 const p = x === 0 ? '0%' : `-${x}00%`;
93 95  
94 96 let style = {};
... ... @@ -124,13 +126,13 @@
124 126 this.navList.push({
125 127 label: pane.label,
126 128 icon: pane.icon || '',
127   - key: pane.key || index,
  129 + name: pane.currentName || index,
128 130 disabled: pane.disabled,
129 131 closable: pane.closable
130 132 });
131   - if (!pane.key) pane.key = index;
  133 + if (!pane.currentName) pane.currentName = index;
132 134 if (index === 0) {
133   - if (!this.activeKey) this.activeKey = pane.key || index;
  135 + if (!this.activeKey) this.activeKey = pane.currentName || index;
134 136 }
135 137 });
136 138 this.updateStatus();
... ... @@ -138,8 +140,8 @@
138 140 },
139 141 updateBar () {
140 142 this.$nextTick(() => {
141   - const index = this.navList.findIndex((nav) => nav.key === this.activeKey);
142   - const prevTabs = this.$els.nav.querySelectorAll(`.${prefixCls}-tab`);
  143 + const index = this.navList.findIndex((nav) => nav.name === this.activeKey);
  144 + const prevTabs = this.$refs.nav.querySelectorAll(`.${prefixCls}-tab`);
143 145 const tab = prevTabs[index];
144 146 this.barWidth = parseFloat(getStyle(tab, 'width'));
145 147  
... ... @@ -158,29 +160,30 @@
158 160 },
159 161 updateStatus () {
160 162 const tabs = this.getTabs();
161   - tabs.forEach(tab => tab.show = (tab.key === this.activeKey) || this.animated);
  163 + tabs.forEach(tab => tab.show = (tab.currentName === this.activeKey) || this.animated);
162 164 },
163 165 tabCls (item) {
164 166 return [
165 167 `${prefixCls}-tab`,
166 168 {
167 169 [`${prefixCls}-tab-disabled`]: item.disabled,
168   - [`${prefixCls}-tab-active`]: item.key === this.activeKey
  170 + [`${prefixCls}-tab-active`]: item.name === this.activeKey
169 171 }
170 172 ];
171 173 },
172 174 handleChange (index) {
173 175 const nav = this.navList[index];
174 176 if (nav.disabled) return;
175   - this.activeKey = nav.key;
176   - this.$emit('on-click', nav.key);
  177 + this.activeKey = nav.name;
  178 + this.$emit('input', nav.name);
  179 + this.$emit('on-click', nav.name);
177 180 },
178 181 handleRemove (index) {
179 182 const tabs = this.getTabs();
180 183 const tab = tabs[index];
181 184 tab.$destroy(true);
182 185  
183   - if (tab.key === this.activeKey) {
  186 + if (tab.currentName === this.activeKey) {
184 187 const newTabs = this.getTabs();
185 188 let activeKey = -1;
186 189  
... ... @@ -189,16 +192,16 @@
189 192 const rightNoDisabledTabs = tabs.filter((item, itemIndex) => !item.disabled && itemIndex > index);
190 193  
191 194 if (rightNoDisabledTabs.length) {
192   - activeKey = rightNoDisabledTabs[0].key;
  195 + activeKey = rightNoDisabledTabs[0].currentName;
193 196 } else if (leftNoDisabledTabs.length) {
194   - activeKey = leftNoDisabledTabs[leftNoDisabledTabs.length - 1].key;
  197 + activeKey = leftNoDisabledTabs[leftNoDisabledTabs.length - 1].currentName;
195 198 } else {
196   - activeKey = newTabs[0].key;
  199 + activeKey = newTabs[0].currentName;
197 200 }
198 201 }
199 202 this.activeKey = activeKey;
200 203 }
201   - this.$emit('on-tab-remove', tab.key);
  204 + this.$emit('on-tab-remove', tab.currentName);
202 205 this.updateNav();
203 206 },
204 207 showClose (item) {
... ... @@ -214,6 +217,9 @@
214 217 }
215 218 },
216 219 watch: {
  220 + value (val) {
  221 + this.activeKey = val;
  222 + },
217 223 activeKey () {
218 224 this.updateBar();
219 225 this.updateStatus();
... ...
src/index.js
... ... @@ -34,7 +34,7 @@ import Rate from &#39;./components/rate&#39;;
34 34 import Steps from './components/steps';
35 35 import Switch from './components/switch';
36 36 // import Table from './components/table';
37   -// import Tabs from './components/tabs';
  37 +import Tabs from './components/tabs';
38 38 import Tag from './components/tag';
39 39 import Timeline from './components/timeline';
40 40 // import TimePicker from './components/time-picker';
... ... @@ -100,8 +100,8 @@ const iview = {
100 100 Steps,
101 101 iSwitch: Switch,
102 102 // iTable: Table,
103   - // Tabs: Tabs,
104   - // TabPane: Tabs.Pane,
  103 + Tabs: Tabs,
  104 + TabPane: Tabs.Pane,
105 105 Tag,
106 106 Timeline,
107 107 TimelineItem: Timeline.Item,
... ...
test/app.vue
... ... @@ -34,6 +34,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; }
34 34 <li><router-link to="/tree">Tree</router-link></li>
35 35 <li><router-link to="/rate">Rate</router-link></li>
36 36 <li><router-link to="/circle">Circle</router-link></li>
  37 + <li><router-link to="/tabs">Tabs</router-link></li>
37 38 </ul>
38 39 </nav>
39 40 <router-view></router-view>
... ...
test/main.js
... ... @@ -100,6 +100,10 @@ const router = new VueRouter({
100 100 {
101 101 path: '/circle',
102 102 component: require('./routers/circle.vue')
  103 + },
  104 + {
  105 + path: '/tabs',
  106 + component: require('./routers/tabs.vue')
103 107 }
104 108 ]
105 109 });
... ...
test/routers/tabs.vue
  1 +<style>
  2 + .demo-tabs-style1 > .ivu-tabs-card > .ivu-tabs-content {
  3 + height: 120px;
  4 + margin-top: -16px;
  5 + }
  6 +
  7 + .demo-tabs-style1 > .ivu-tabs-card > .ivu-tabs-content > .ivu-tabs-tabpane {
  8 + background: #fff;
  9 + padding: 16px;
  10 + }
  11 +
  12 + .demo-tabs-style1 > .ivu-tabs.ivu-tabs-card > .ivu-tabs-bar .ivu-tabs-tab {
  13 + border-color: transparent;
  14 + }
  15 +
  16 + .demo-tabs-style1 > .ivu-tabs-card > .ivu-tabs-bar .ivu-tabs-tab-active {
  17 + border-color: #fff;
  18 + }
  19 + .demo-tabs-style2 > .ivu-tabs.ivu-tabs-card > .ivu-tabs-bar .ivu-tabs-tab{
  20 + border-radius: 0;
  21 + background: #fff;
  22 + }
  23 + .demo-tabs-style2 > .ivu-tabs.ivu-tabs-card > .ivu-tabs-bar .ivu-tabs-tab-active{
  24 + border-top: 1px solid #3399ff;
  25 + }
  26 + .demo-tabs-style2 > .ivu-tabs.ivu-tabs-card > .ivu-tabs-bar .ivu-tabs-tab-active:before{
  27 + content: '';
  28 + display: block;
  29 + width: 100%;
  30 + height: 1px;
  31 + background: #3399ff;
  32 + position: absolute;
  33 + top: 0;
  34 + left: 0;
  35 + }
  36 +</style>
1 37 <template>
2   - <Tabs active-key="key1">
3   - <Tab-pane label="标签一" key="key1">标签一的内容</Tab-pane>
4   - <Tab-pane label="标签二" key="key2">标签二的内容</Tab-pane>
5   - <Tab-pane label="标签三" key="key3">标签三的内容</Tab-pane>
6   - </Tabs>
7   - <Tabs type="card" >
8   - <Tab-pane label="标签一">标签一的内容</Tab-pane>
9   - <Tab-pane label="标签二" :closable="true">标签二的内容</Tab-pane>
10   - <Tab-pane label="标签三">标签三的内容</Tab-pane>
11   - </Tabs>
  38 + <Row :gutter="32">
  39 + <i-col span="12" class="demo-tabs-style1" style="background: #e3e8ee;padding:16px;">
  40 + <Tabs type="card">
  41 + <Tab-pane label="标签一">标签一的内容</Tab-pane>
  42 + <Tab-pane label="标签二">标签二的内容</Tab-pane>
  43 + <Tab-pane label="标签三">标签三的内容</Tab-pane>
  44 + </Tabs>
  45 + </i-col>
  46 + <i-col span="12" class="demo-tabs-style2">
  47 + <Tabs type="card">
  48 + <Tab-pane label="标签一">标签一的内容</Tab-pane>
  49 + <Tab-pane label="标签二">标签二的内容</Tab-pane>
  50 + <Tab-pane label="标签三">标签三的内容</Tab-pane>
  51 + </Tabs>
  52 + </i-col>
  53 + </Row>
12 54 </template>
13 55 <script>
14 56 export default {
... ...