Skip to content

Commit

Permalink
[new feature] Tab: add name prop (#3762)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored Jul 5, 2019
1 parent 2389ac0 commit b802047
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 84 deletions.
33 changes: 27 additions & 6 deletions src/tab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,26 @@ export default {
}
```

### Match By Name

```html
<van-tabs v-model="activeName">
<van-tab title="tab 1" name="a">content of tab 1</van-tab>
<van-tab title="tab 2" name="b">content of tab 2</van-tab>
<van-tab title="tab 3" name="c">content of tab 3</van-tab>
</van-tabs>
```

```js
export default {
data() {
return {
activeName: 'a'
};
}
}
```

### Swipe Tabs

By default more than 4 tabs, you can scroll through the tabs. You can set `swipe-threshold` attribute to customize threshold number.
Expand Down Expand Up @@ -59,7 +79,7 @@ You can set `disabled` attribute on the corresponding `van-tab`.
```javascript
export default {
methods: {
onClickDisabled(index, title) {
onClickDisabled(name, title) {
this.$toast(title + ' is disabled');
}
}
Expand Down Expand Up @@ -91,7 +111,7 @@ Tabs styled as cards.
```javascript
export default {
methods: {
onClick(index, title) {
onClick(name, title) {
this.$toast(title);
}
}
Expand Down Expand Up @@ -155,7 +175,7 @@ In swipeable mode, you can switch tabs with swipe gestrue in the content

| Attribute | Description | Type | Default |
|------|------|------|------|
| v-model | Index of active tab | `String` `Number` | `0` |
| v-model | Index of active tab | `String | Number` | `0` |
| type | Can be set to `line` `card` | `String` | `line` |
| duration | Toggle tab's animation time | `Number` | `0.3` | - |
| background | Background color | `String` | `white` |
Expand All @@ -177,6 +197,7 @@ In swipeable mode, you can switch tabs with swipe gestrue in the content

| Attribute | Description | Type | Default |
|------|------|------|------|
| name | Identifier | `String | Number` | Index of tab |
| title | Title | `String` | - |
| disabled | Whether to disable tab | `Boolean` | `false` |

Expand All @@ -198,7 +219,7 @@ In swipeable mode, you can switch tabs with swipe gestrue in the content

| Event | Description | Arguments |
|------|------|------|
| click | Triggered when click tab | index:index of current tab,title: tab title |
| change | Triggered when active tab changed | index:index of current tab,title: tab title |
| disabled | Triggered when click disabled tab | index:index of current tab, title: tab title |
| click | Triggered when click tab | name:name of current tab,title: tab title |
| change | Triggered when active tab changed | name:name of current tab,title: tab title |
| disabled | Triggered when click disabled tab | name:name of current tab, title: tab title |
| scroll | Triggered when tab scroll in sticky mode | Object: { scrollTop, isFixed } |
43 changes: 33 additions & 10 deletions src/tab/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Vue.use(Tab).use(Tabs);

### 基础用法

默认情况下启用第一个标签,可以通过`v-model`绑定当前激活的标签索引
通过`v-model`绑定当前激活标签对应的索引值,默认情况下启用第一个标签

```html
<van-tabs v-model="active">
Expand All @@ -33,9 +33,31 @@ export default {
}
```

### 横向滚动
### 通过名称匹配

多于 4 个标签时,Tab 可以横向滚动
在标签指定`name`属性的情况下,`v-model`的值为当前标签的`name`

```html
<van-tabs v-model="activeName">
<van-tab title="标签 1" name="a">内容 1</van-tab>
<van-tab title="标签 2" name="b">内容 2</van-tab>
<van-tab title="标签 3" name="c">内容 3</van-tab>
</van-tabs>
```

```js
export default {
data() {
return {
activeName: 'a'
};
}
}
```

### 标签栏滚动

标签数量超过 4 个时,标签栏可以在水平方向上滚动,切换时会自动将当前标签居中

```html
<van-tabs>
Expand All @@ -60,8 +82,8 @@ export default {
```javascript
export default {
methods: {
onClickDisabled(index, title) {
this.$toast(title + '已被禁用');
onClickDisabled(name, title) {
this.$toast(name + '已被禁用');
}
}
};
Expand Down Expand Up @@ -93,7 +115,7 @@ export default {
```javascript
export default {
methods: {
onClick(index, title) {
onClick(name, title) {
this.$toast(title);
}
}
Expand Down Expand Up @@ -157,7 +179,7 @@ export default {

| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|------|------|
| v-model | 当前标签的索引 | `String` `Number` | `0` | - |
| v-model | 绑定当前选中标签的标识符 | `String | Number` | `0` | - |
| type | 样式类型,可选值为`card` | `String` | `line` | - |
| duration | 动画时间,单位秒 | `Number` | `0.3` | - |
| background | 标签栏背景色 | `String` | `white` | 1.6.5 |
Expand All @@ -179,6 +201,7 @@ export default {

| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|------|------|
| name | 标签名称,作为匹配的标识符 | `String | Number` | 标签的索引值 | 2.0.6 |
| title | 标题 | `String` | - | - |
| disabled | 是否禁用标签 | `Boolean` | `false` | - |

Expand All @@ -200,7 +223,7 @@ export default {

| 事件名 | 说明 | 回调参数 |
|------|------|------|
| click | 点击标签时触发 | index:标签索引,title:标题 |
| change | 当前激活的标签改变时触发 | index:标签索引,title:标题 |
| disabled | 点击被禁用的标签时触发 | index:标签索引,title:标题 |
| click | 点击标签时触发 | name:标签标识符,title:标题 |
| change | 当前激活的标签改变时触发 | name:标签标识符,title:标题 |
| disabled | 点击被禁用的标签时触发 | name:标签标识符,title:标题 |
| scroll | 滚动时触发,仅在 sticky 模式下生效 | { scrollTop: 距离顶部位置, isFixed: 是否吸顶 } |
38 changes: 30 additions & 8 deletions src/tab/demo/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,31 @@
</van-tabs>
</demo-block>

<demo-block :title="$t('matchByName')">
<van-tabs v-model="activeName">
<van-tab
name="a"
:title="$t('tab') + 1"
>
{{ $t('content') }} 1
</van-tab>
<van-tab
name="b"
:title="$t('tab') + 2"
>
{{ $t('content') }} 2
</van-tab>
<van-tab
name="c"
:title="$t('tab') + 3"
>
{{ $t('content') }} 3
</van-tab>
</van-tabs>
</demo-block>

<demo-block :title="$t('title2')">
<van-tabs @scroll="onScroll">
<van-tabs>
<van-tab
v-for="index in 8"
:title="$t('tab') + index"
Expand Down Expand Up @@ -124,15 +147,16 @@ export default {
i18n: {
'zh-CN': {
tab: '标签 ',
title2: '横向滚动',
title2: '标签栏滚动',
title3: '禁用标签',
title4: '样式风格',
title5: '点击事件',
title6: '粘性布局',
title7: '自定义标签',
title8: '切换动画',
title9: '滑动切换',
disabled: ' 已被禁用'
disabled: ' 已被禁用',
matchByName: '通过名称匹配'
},
'en-US': {
tab: 'Tab ',
Expand All @@ -145,13 +169,15 @@ export default {
title7: 'Custom Tab',
title8: 'Switch Animation',
title9: 'Swipeable',
disabled: ' is disabled'
disabled: ' is disabled',
matchByName: 'Match By Name'
}
},
data() {
return {
active: 2,
activeName: 'b',
tabs: [1, 2, 3, 4]
};
},
Expand All @@ -163,10 +189,6 @@ export default {
onClick(index, title) {
this.$toast(title);
},
onScroll(e) {
console.log(e);
}
}
};
Expand Down
21 changes: 13 additions & 8 deletions src/tab/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default createComponent({
mixins: [ChildrenMixin('vanTabs')],

props: {
name: [String, Number],
title: String,
disabled: Boolean
},
Expand All @@ -19,14 +20,18 @@ export default createComponent({
},

computed: {
selected() {
return this.index === this.parent.curActive;
computedName() {
return this.name || this.index;
},

isActive() {
return this.computedName === this.parent.currentName;
}
},

watch: {
'parent.curActive'() {
this.inited = this.inited || this.selected;
'parent.currentIndex'() {
this.inited = this.inited || this.isActive;
},

title() {
Expand All @@ -41,7 +46,7 @@ export default createComponent({
},

render(h) {
const { slots, selected } = this;
const { slots, isActive } = this;
const shouldRender = this.inited || !this.parent.lazyRender;
const Content = [shouldRender ? slots() : h()];

Expand All @@ -53,16 +58,16 @@ export default createComponent({
return (
<div
role="tabpanel"
aria-hidden={!selected}
class={bem('pane-wrapper', { inactive: !selected })}
aria-hidden={!isActive}
class={bem('pane-wrapper', { inactive: !isActive })}
>
<div class={bem('pane')}>{Content}</div>
</div>
);
}

return (
<div vShow={selected} role="tabpanel" class={bem('pane')}>
<div vShow={isActive} role="tabpanel" class={bem('pane')}>
{Content}
</div>
);
Expand Down
23 changes: 23 additions & 0 deletions src/tab/test/__snapshots__/demo.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,29 @@ exports[`renders demo correctly 1`] = `
</div>
</div>
</div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div role="tablist" class="van-tabs__nav van-tabs__nav--line">
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 1</span></div>
<div role="tab" aria-selected="true" class="van-tab van-tab--active"><span class="van-ellipsis">标签 2</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 3</span></div>
<div class="van-tabs__line" style="width: 0px; transform: translateX(0px) translateX(-50%);"></div>
</div>
</div>
<div class="van-tabs__content">
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="">
内容 2
</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
</div>
</div>
</div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-tabs__wrap--scrollable van-hairline--top-bottom">
Expand Down
22 changes: 22 additions & 0 deletions src/tab/test/__snapshots__/index.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,28 @@ exports[`lazy render 2`] = `
</div>
`;

exports[`name prop 1`] = `
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div role="tablist" class="van-tabs__nav van-tabs__nav--line">
<div role="tab" aria-selected="true" class="van-tab van-tab--active"><span class="van-ellipsis">title1</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">title2</span></div>
<div role="tab" class="van-tab van-tab--disabled"><span class="van-ellipsis">title3</span></div>
<div class="van-tabs__line"></div>
</div>
</div>
<div class="van-tabs__content">
<div role="tabpanel" class="van-tab__pane">Text</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
</div>
</div>
`;

exports[`render nav-left & nav-right slot 1`] = `
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-hairline--top-bottom">
Expand Down
Loading

0 comments on commit b802047

Please sign in to comment.