Commit 30510c3d9e7850fb52691a6f9fdc5a7592002591

Authored by 梁灏
1 parent b2d29401

support Tabs

support Tabs
@@ -25,4 +25,6 @@ class 改为了 className @@ -25,4 +25,6 @@ class 改为了 className
25 ### Tree 25 ### Tree
26 废弃 data,改为 value,使用 v-model,key 更名为 name,不能再 template 的prop 上使用 this 26 废弃 data,改为 value,使用 v-model,key 更名为 name,不能再 template 的prop 上使用 this
27 ### Circle 27 ### Circle
28 -改名为 iCircle  
29 \ No newline at end of file 28 \ No newline at end of file
  29 +改名为 iCircle
  30 +### Tabs
  31 +废弃 activeKey,改用 value,使用 v-model,key 更名为 name
30 \ No newline at end of file 32 \ No newline at end of file
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 - [x] Carousel 50 - [x] Carousel
51 - [x] Tree 51 - [x] Tree
52 - [ ] Menu 52 - [ ] Menu
53 -- [ ] Tabs 53 +- [x] Tabs
54 - [ ] Dropdown 54 - [ ] Dropdown
55 - [ ] Page 55 - [ ] Page
56 - [ ] Breadcrumb 56 - [ ] Breadcrumb
src/components/tabs/pane.vue
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 export default { 7 export default {
8 name: 'TabPane', 8 name: 'TabPane',
9 props: { 9 props: {
10 - key: { 10 + name: {
11 type: String 11 type: String
12 }, 12 },
13 label: { 13 label: {
@@ -29,7 +29,8 @@ @@ -29,7 +29,8 @@
29 data () { 29 data () {
30 return { 30 return {
31 prefixCls: prefixCls, 31 prefixCls: prefixCls,
32 - show: true 32 + show: true,
  33 + currentName: this.name
33 }; 34 };
34 }, 35 },
35 methods: { 36 methods: {
@@ -38,6 +39,10 @@ @@ -38,6 +39,10 @@
38 } 39 }
39 }, 40 },
40 watch: { 41 watch: {
  42 + name (val) {
  43 + this.currentName = val;
  44 + this.updateNav();
  45 + },
41 label () { 46 label () {
42 this.updateNav(); 47 this.updateNav();
43 }, 48 },
@@ -48,7 +53,7 @@ @@ -48,7 +53,7 @@
48 this.updateNav(); 53 this.updateNav();
49 } 54 }
50 }, 55 },
51 - ready () { 56 + mounted () {
52 this.updateNav(); 57 this.updateNav();
53 } 58 }
54 }; 59 };
src/components/tabs/tabs.vue
@@ -4,12 +4,12 @@ @@ -4,12 +4,12 @@
4 <div :class="[prefixCls + '-nav-container']"> 4 <div :class="[prefixCls + '-nav-container']">
5 <div :class="[prefixCls + '-nav-wrap']"> 5 <div :class="[prefixCls + '-nav-wrap']">
6 <div :class="[prefixCls + '-nav-scroll']"> 6 <div :class="[prefixCls + '-nav-scroll']">
7 - <div :class="[prefixCls + '-nav']" v-el:nav> 7 + <div :class="[prefixCls + '-nav']" ref="nav">
8 <div :class="barClasses" :style="barStyle"></div> 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 <Icon v-if="item.icon !== ''" :type="item.icon"></Icon> 10 <Icon v-if="item.icon !== ''" :type="item.icon"></Icon>
11 {{ item.label }} 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 </div> 13 </div>
14 </div> 14 </div>
15 </div> 15 </div>
@@ -26,9 +26,10 @@ @@ -26,9 +26,10 @@
26 const prefixCls = 'ivu-tabs'; 26 const prefixCls = 'ivu-tabs';
27 27
28 export default { 28 export default {
  29 + name: 'Tabs',
29 components: { Icon }, 30 components: { Icon },
30 props: { 31 props: {
31 - activeKey: { 32 + value: {
32 type: [String, Number] 33 type: [String, Number]
33 }, 34 },
34 type: { 35 type: {
@@ -57,7 +58,8 @@ @@ -57,7 +58,8 @@
57 prefixCls: prefixCls, 58 prefixCls: prefixCls,
58 navList: [], 59 navList: [],
59 barWidth: 0, 60 barWidth: 0,
60 - barOffset: 0 61 + barOffset: 0,
  62 + activeKey: this.value
61 }; 63 };
62 }, 64 },
63 computed: { 65 computed: {
@@ -88,7 +90,7 @@ @@ -88,7 +90,7 @@
88 ]; 90 ];
89 }, 91 },
90 contentStyle () { 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 const p = x === 0 ? '0%' : `-${x}00%`; 94 const p = x === 0 ? '0%' : `-${x}00%`;
93 95
94 let style = {}; 96 let style = {};
@@ -124,13 +126,13 @@ @@ -124,13 +126,13 @@
124 this.navList.push({ 126 this.navList.push({
125 label: pane.label, 127 label: pane.label,
126 icon: pane.icon || '', 128 icon: pane.icon || '',
127 - key: pane.key || index, 129 + name: pane.currentName || index,
128 disabled: pane.disabled, 130 disabled: pane.disabled,
129 closable: pane.closable 131 closable: pane.closable
130 }); 132 });
131 - if (!pane.key) pane.key = index; 133 + if (!pane.currentName) pane.currentName = index;
132 if (index === 0) { 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 this.updateStatus(); 138 this.updateStatus();
@@ -138,8 +140,8 @@ @@ -138,8 +140,8 @@
138 }, 140 },
139 updateBar () { 141 updateBar () {
140 this.$nextTick(() => { 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 const tab = prevTabs[index]; 145 const tab = prevTabs[index];
144 this.barWidth = parseFloat(getStyle(tab, 'width')); 146 this.barWidth = parseFloat(getStyle(tab, 'width'));
145 147
@@ -158,29 +160,30 @@ @@ -158,29 +160,30 @@
158 }, 160 },
159 updateStatus () { 161 updateStatus () {
160 const tabs = this.getTabs(); 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 tabCls (item) { 165 tabCls (item) {
164 return [ 166 return [
165 `${prefixCls}-tab`, 167 `${prefixCls}-tab`,
166 { 168 {
167 [`${prefixCls}-tab-disabled`]: item.disabled, 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 handleChange (index) { 174 handleChange (index) {
173 const nav = this.navList[index]; 175 const nav = this.navList[index];
174 if (nav.disabled) return; 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 handleRemove (index) { 181 handleRemove (index) {
179 const tabs = this.getTabs(); 182 const tabs = this.getTabs();
180 const tab = tabs[index]; 183 const tab = tabs[index];
181 tab.$destroy(true); 184 tab.$destroy(true);
182 185
183 - if (tab.key === this.activeKey) { 186 + if (tab.currentName === this.activeKey) {
184 const newTabs = this.getTabs(); 187 const newTabs = this.getTabs();
185 let activeKey = -1; 188 let activeKey = -1;
186 189
@@ -189,16 +192,16 @@ @@ -189,16 +192,16 @@
189 const rightNoDisabledTabs = tabs.filter((item, itemIndex) => !item.disabled && itemIndex > index); 192 const rightNoDisabledTabs = tabs.filter((item, itemIndex) => !item.disabled && itemIndex > index);
190 193
191 if (rightNoDisabledTabs.length) { 194 if (rightNoDisabledTabs.length) {
192 - activeKey = rightNoDisabledTabs[0].key; 195 + activeKey = rightNoDisabledTabs[0].currentName;
193 } else if (leftNoDisabledTabs.length) { 196 } else if (leftNoDisabledTabs.length) {
194 - activeKey = leftNoDisabledTabs[leftNoDisabledTabs.length - 1].key; 197 + activeKey = leftNoDisabledTabs[leftNoDisabledTabs.length - 1].currentName;
195 } else { 198 } else {
196 - activeKey = newTabs[0].key; 199 + activeKey = newTabs[0].currentName;
197 } 200 }
198 } 201 }
199 this.activeKey = activeKey; 202 this.activeKey = activeKey;
200 } 203 }
201 - this.$emit('on-tab-remove', tab.key); 204 + this.$emit('on-tab-remove', tab.currentName);
202 this.updateNav(); 205 this.updateNav();
203 }, 206 },
204 showClose (item) { 207 showClose (item) {
@@ -214,6 +217,9 @@ @@ -214,6 +217,9 @@
214 } 217 }
215 }, 218 },
216 watch: { 219 watch: {
  220 + value (val) {
  221 + this.activeKey = val;
  222 + },
217 activeKey () { 223 activeKey () {
218 this.updateBar(); 224 this.updateBar();
219 this.updateStatus(); 225 this.updateStatus();
@@ -34,7 +34,7 @@ import Rate from &#39;./components/rate&#39;; @@ -34,7 +34,7 @@ import Rate from &#39;./components/rate&#39;;
34 import Steps from './components/steps'; 34 import Steps from './components/steps';
35 import Switch from './components/switch'; 35 import Switch from './components/switch';
36 // import Table from './components/table'; 36 // import Table from './components/table';
37 -// import Tabs from './components/tabs'; 37 +import Tabs from './components/tabs';
38 import Tag from './components/tag'; 38 import Tag from './components/tag';
39 import Timeline from './components/timeline'; 39 import Timeline from './components/timeline';
40 // import TimePicker from './components/time-picker'; 40 // import TimePicker from './components/time-picker';
@@ -100,8 +100,8 @@ const iview = { @@ -100,8 +100,8 @@ const iview = {
100 Steps, 100 Steps,
101 iSwitch: Switch, 101 iSwitch: Switch,
102 // iTable: Table, 102 // iTable: Table,
103 - // Tabs: Tabs,  
104 - // TabPane: Tabs.Pane, 103 + Tabs: Tabs,
  104 + TabPane: Tabs.Pane,
105 Tag, 105 Tag,
106 Timeline, 106 Timeline,
107 TimelineItem: Timeline.Item, 107 TimelineItem: Timeline.Item,
@@ -34,6 +34,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; } @@ -34,6 +34,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; }
34 <li><router-link to="/tree">Tree</router-link></li> 34 <li><router-link to="/tree">Tree</router-link></li>
35 <li><router-link to="/rate">Rate</router-link></li> 35 <li><router-link to="/rate">Rate</router-link></li>
36 <li><router-link to="/circle">Circle</router-link></li> 36 <li><router-link to="/circle">Circle</router-link></li>
  37 + <li><router-link to="/tabs">Tabs</router-link></li>
37 </ul> 38 </ul>
38 </nav> 39 </nav>
39 <router-view></router-view> 40 <router-view></router-view>
@@ -100,6 +100,10 @@ const router = new VueRouter({ @@ -100,6 +100,10 @@ const router = new VueRouter({
100 { 100 {
101 path: '/circle', 101 path: '/circle',
102 component: require('./routers/circle.vue') 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 <template> 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 </template> 54 </template>
13 <script> 55 <script>
14 export default { 56 export default {