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 | 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
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 './components/rate'; |
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
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 { | ... | ... |