[Improvement] Tab: support v-model bind active tab (#879)

This commit is contained in:
neverland 2018-04-16 19:11:48 +08:00 committed by GitHub
parent 2ce0803ffe
commit ed1bff1052
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 18 deletions

View File

@ -1,7 +1,7 @@
<template>
<demo-section>
<demo-block :title="$t('basicUsage')">
<van-tabs :active="active">
<van-tabs v-model="active">
<van-tab :title="$t('tab') + index" v-for="index in tabs" :key="index">
{{ $t('content') }} {{ index }}
</van-tab>

View File

@ -11,10 +11,10 @@ Vue.use(Tab).use(Tabs);
#### Basic Usage
By default, the first tab is actived. You can set `active` attribute on `van-tabs` to active specified tab.
The first tab is actived by default, you can set `v-model` to active specified tab.
```html
<van-tabs :active="active">
<van-tabs v-model="active">
<van-tab v-for="index in 4" :title="'tab' + index">
content of tab {{ index }}
</van-tab>
@ -101,7 +101,7 @@ export default {
In sticky mode, the tab will be fixed to top when scroll to top
```html
<van-tabs :active="active" sticky>
<van-tabs v-model="active" sticky>
<van-tab v-for="index in 4" :title="'tab ' + index">
content {{ index }}
</van-tab>
@ -112,7 +112,7 @@ In sticky mode, the tab will be fixed to top when scroll to top
Use title slot to custom tab title
```html
<van-tabs :active="active">
<van-tabs v-model="active">
<van-tab v-for="index in 2">
<div slot="title">
<van-icon name="more-o" />tab
@ -127,7 +127,7 @@ Use title slot to custom tab title
In swipeable mode, you can switch tabs with swipe gestrue in the content
```html
<van-tabs :active="active" swipeable>
<van-tabs v-model="active" swipeable>
<van-tab v-for="index in 4" :title="'tab ' + index">
content {{ index }}
</van-tab>
@ -138,8 +138,8 @@ In swipeable mode, you can switch tabs with swipe gestrue in the content
| Attribute | Description | Type | Default | Accepted Values |
|-----------|-----------|-----------|-------------|-------------|
| v-model | Index of active tab | `String` `Number` | `0` | - |
| type | There are two style tabs, set this attribute to change tab style | `String` | `line` | `card` |
| active | Index of active tab | `String` `Number` | `0` | - |
| duration | Toggle tab's animation time | `Number` | `0.2` | - | - |
| swipe-threshold | Set swipe tabs threshold | `Number` | `4` | - | - |
| sticky | Whether to use sticky mode | `Boolean` | `false` | - |

View File

@ -11,10 +11,10 @@ Vue.use(Tab).use(Tabs);
#### 基础用法
默认情况下启用第一个 tab可以通过`active`属性激活对应特定索引的 tab
默认情况下启用第一个 tab可以通过`v-model`绑定当前激活的标签索引
```html
<van-tabs :active="active">
<van-tabs v-model="active">
<van-tab v-for="index in 4" :title="'选项 ' + index">
内容 {{ index }}
</van-tab>
@ -103,7 +103,7 @@ export default {
通过`sticky`属性可以开启粘性布局,粘性布局下,当 Tab 滚动到顶部时会自动吸顶
```html
<van-tabs :active="active" sticky>
<van-tabs v-model="active" sticky>
<van-tab v-for="index in 4" :title="'选项 ' + index">
内容 {{ index }}
</van-tab>
@ -114,7 +114,7 @@ export default {
通过 title slot 可以自定义标签内容
```html
<van-tabs :active="active">
<van-tabs v-model="active">
<van-tab v-for="index in 2">
<div slot="title">
<van-icon name="more-o" />选项
@ -129,7 +129,7 @@ export default {
通过`swipeable`属性可以开启滑动切换tab
```html
<van-tabs :active="active" swipeable>
<van-tabs v-model="active" swipeable>
<van-tab v-for="index in 4" :title="'选项 ' + index">
内容 {{ index }}
</van-tab>
@ -140,8 +140,8 @@ export default {
| 参数 | 说明 | 类型 | 默认值 | 可选 |
|-----------|-----------|-----------|-------------|-------------|
| v-model | 当前激活的 tab | `String` `Number` | `0` | - |
| type | Tab 样式类型 | `String` | `line` | `card` |
| active | 默认激活的 tab | `String` `Number` | `0` | - |
| duration | 切换 tab 的动画时间 | `Number` | `0.2` | - |
| swipe-threshold | 滚动阀值,设置 Tab 超过多少个可滚动 | `Number` | `4` | - |
| sticky | 是否使用粘性定位布局 | `Boolean` | `false` | - |

View File

@ -49,6 +49,10 @@ export default create({
VanNode
},
model: {
prop: 'active'
},
props: {
sticky: Boolean,
active: {
@ -88,7 +92,9 @@ export default create({
watch: {
active(val) {
this.correctActive(val);
if (val !== this.curActive) {
this.correctActive(val);
}
},
tabs(tabs) {
@ -166,9 +172,9 @@ export default create({
if (direction === 'horizontal' && this.offsetX >= minSwipeDistance) {
/* istanbul ignore else */
if (deltaX > 0 && curActive !== 0) {
this.curActive = curActive - 1;
this.setCurActive(curActive - 1);
} else if (deltaX < 0 && curActive !== this.tabs.length - 1) {
this.curActive = curActive + 1;
this.setCurActive(curActive + 1);
}
}
},
@ -208,7 +214,12 @@ export default create({
active = +active;
const exist = this.tabs.some(tab => tab.index === active);
const defaultActive = (this.tabs[0] || {}).index || 0;
this.curActive = exist ? active : defaultActive;
this.setCurActive(exist ? active : defaultActive);
},
setCurActive(active) {
this.curActive = active;
this.$emit('input', active);
},
// emit event when clicked
@ -218,7 +229,7 @@ export default create({
this.$emit('disabled', index, title);
} else {
this.$emit('click', index, title);
this.curActive = index;
this.setCurActive(index);
}
},