Commit 30510c3d9e7850fb52691a6f9fdc5a7592002591
1 parent
b2d29401
support Tabs
support Tabs
Showing
8 changed files
with
98 additions
and
38 deletions
Show diff stats
CHANGE.md
@@ -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 |
README.md
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(); |
src/index.js
@@ -34,7 +34,7 @@ import Rate from './components/rate'; | @@ -34,7 +34,7 @@ import Rate from './components/rate'; | ||
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, |
test/app.vue
@@ -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> |
test/main.js
@@ -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 { |