[improvement] rename packages dir to src (#3659)

This commit is contained in:
neverland
2019-06-27 11:25:57 +08:00
committed by GitHub
parent 8489918dca
commit 75c79b7044
619 changed files with 21 additions and 21 deletions
+195
View File
@@ -0,0 +1,195 @@
<template>
<demo-section>
<demo-block :title="$t('basicUsage')">
<van-tabs v-model="active">
<van-tab
:title="$t('tab') + index"
v-for="index in tabs"
:key="index"
>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
<demo-block :title="$t('title2')">
<van-tabs @scroll="onScroll">
<van-tab
v-for="index in 8"
:title="$t('tab') + index"
:key="index"
>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
<demo-block :title="$t('title3')">
<van-tabs @disabled="onClickDisabled">
<van-tab
v-for="index in 3"
:title="$t('tab') + index"
:disabled="index === 2"
:key="index"
>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
<demo-block :title="$t('title4')">
<van-tabs type="card">
<van-tab
v-for="index in 3"
:title="$t('tab') + index"
:key="index"
>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
<demo-block :title="$t('title5')">
<van-tabs @click="onClick">
<van-tab
v-for="index in 2"
:title="$t('tab') + index"
:key="index"
>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
<demo-block :title="$t('title6')">
<van-tabs
:active="active"
sticky
>
<van-tab
:title="$t('tab') + index"
v-for="index in tabs"
:key="index"
>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
<demo-block :title="$t('title7')">
<van-tabs :active="active">
<van-tab
v-for="index in 2"
:key="index"
>
<template #title>
<van-icon name="more-o" />{{ $t('tab') }}
</template>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
<demo-block :title="$t('title8')">
<van-tabs animated>
<van-tab
:title="$t('tab') + index"
v-for="index in tabs"
:key="index"
>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
<demo-block :title="$t('title9')">
<van-tabs
:active="active"
swipeable
>
<van-tab
:title="$t('tab') + index"
v-for="index in tabs"
:key="index"
>
{{ $t('content') }} {{ index }}
</van-tab>
</van-tabs>
</demo-block>
</demo-section>
</template>
<script>
export default {
i18n: {
'zh-CN': {
tab: '标签 ',
title2: '横向滚动',
title3: '禁用标签',
title4: '样式风格',
title5: '点击事件',
title6: '粘性布局',
title7: '自定义标签',
title8: '切换动画',
title9: '滑动切换',
disabled: ' 已被禁用'
},
'en-US': {
tab: 'Tab ',
content: 'content of tab',
title2: 'Swipe Tabs',
title3: 'Disabled Tab',
title4: 'Card Style',
title5: 'Click Event',
title6: 'Sticky',
title7: 'Custom Tab',
title8: 'Switch Animation',
title9: 'Swipeable',
disabled: ' is disabled'
}
},
data() {
return {
active: 2,
tabs: [1, 2, 3, 4]
};
},
methods: {
onClickDisabled(index, title) {
this.$toast(title + this.$t('disabled'));
},
onClick(index, title) {
this.$toast(title);
},
onScroll(e) {
console.log(e);
}
}
};
</script>
<style lang="less">
@import '../../style/var';
.demo-tab {
margin-bottom: 300px;
.van-tab .van-icon {
margin-right: 5px;
vertical-align: -2px;
}
.van-tab__pane {
padding: 25px 20px;
background-color: @white;
}
.van-tabs--card .van-tab__pane {
background-color: transparent;
}
}
</style>
+204
View File
@@ -0,0 +1,204 @@
# Tab
### Install
``` javascript
import { Tab, Tabs } from 'vant';
Vue.use(Tab).use(Tabs);
```
## Usage
### Basic Usage
The first tab is actived by default, you can set `v-model` to active specified tab.
```html
<van-tabs v-model="active">
<van-tab v-for="index in 4" :title="'tab' + index">
content of tab {{ index }}
</van-tab>
</van-tabs>
```
```js
export default {
data() {
return {
active: 2
};
}
}
```
### Swipe Tabs
By default more than 4 tabs, you can scroll through the tabs. You can set `swipe-threshold` attribute to customize threshold number.
```html
<van-tabs>
<van-tab v-for="index in 8" :title="'tab' + index">
content of tab {{ index }}
</van-tab>
</van-tabs>
```
### Disabled Tab
You can set `disabled` attribute on the corresponding `van-tab`.
```html
<van-tabs @disabled="onClickDisabled">
<van-tab v-for="index in 3" :title="'tab' + index" :disabled="index === 2">
content of tab {{ index }}
</van-tab>
</van-tabs>
```
```javascript
export default {
methods: {
onClickDisabled(index, title) {
this.$toast(title + ' is disabled');
}
}
};
```
### Card Style
Tabs styled as cards.
```html
<van-tabs type="card">
<van-tab v-for="index in 3" :title="'tab' + index">
content of tab {{ index }}
</van-tab>
</van-tabs>
```
### Click Event
```html
<van-tabs @click="onClick">
<van-tab v-for="index in 2" :title="'tab' + index">
content of tab {{ index }}
</van-tab>
</van-tabs>
```
```javascript
export default {
methods: {
onClick(index, title) {
this.$toast(title);
}
}
};
```
### Sticky
In sticky mode, the tab will be fixed to top when scroll to top
```html
<van-tabs v-model="active" sticky>
<van-tab v-for="index in 4" :title="'tab ' + index">
content {{ index }}
</van-tab>
</van-tabs>
```
### Custom title
Use title slot to custom tab title
```html
<van-tabs v-model="active">
<van-tab v-for="index in 2">
<div slot="title">
<van-icon name="more-o" />tab
</div>
content {{ index }}
</van-tab>
</van-tabs>
```
### Switch Animation
Use `animated` props to change tabs with animation
```html
<van-tabs v-model="active" animated>
<van-tab v-for="index in 4" :title="'tab ' + index">
content {{ index }}
</van-tab>
</van-tabs>
```
### Swipeable
In swipeable mode, you can switch tabs with swipe gestrue in the content
```html
<van-tabs v-model="active" swipeable>
<van-tab v-for="index in 4" :title="'tab ' + index">
content {{ index }}
</van-tab>
</van-tabs>
```
## API
### Tabs Props
| Attribute | Description | Type | Default |
|------|------|------|------|
| 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` |
| line-width | Width of tab line | `Number | String` | Width of active tab |
| line-height | Height of tab line | `Number | String` | `3px` |
| color | Tab color | `String` | `#f44` |
| title-active-color | Title active color | `String` | - |
| title-inactive-color | Title inactive color | `String` | - |
| swipe-threshold | Set swipe tabs threshold | `Number` | `4` | - |
| offset-top | Offset top when use sticky mode | `Number` | `0` |
| animated | Whether to change tabs with animation | `Boolean` | `false` |
| border | Whether to show border when `type="line"` | `Boolean` | `true` |
| ellipsis | Whether to ellipsis too long title | `Boolean` | `true` |
| sticky | Whether to use sticky mode | `Boolean` | `false` |
| swipeable | Whether to switch tabs with swipe gestrue in the content | `Boolean` | `false` |
| lazy-render | Whether to enable tab content lazy render | `Boolean` | `true` |
### Tab Props
| Attribute | Description | Type | Default |
|------|------|------|------|
| title | Title | `String` | - |
| disabled | Whether to disable tab | `Boolean` | `false` |
### Tabs Slots
| Name | Description |
|------|------|
| nav-left | Custom nav left content |
| nav-right | Custom nav right content |
### Tab Slots
| Name | Description |
|------|------|
| default | Content of tab |
| title | Custom tab title |
### Tabs Events
| Event | Description | Arguments |
|------|------|------|
| click | Triggered when click tab | indexindex of current tabtitle: tab title |
| change | Triggered when active tab changed | indexindex of current tabtitle: tab title |
| disabled | Triggered when click disabled tab | indexindex of current tab, title: tab title |
| scroll | Triggered when tab scroll in sticky mode | Object: { scrollTop, isFixed } |
+70
View File
@@ -0,0 +1,70 @@
/* eslint-disable object-shorthand */
import { createNamespace } from '../utils';
import { ChildrenMixin } from '../mixins/relation';
const [createComponent, bem] = createNamespace('tab');
export default createComponent({
mixins: [ChildrenMixin('vanTabs')],
props: {
title: String,
disabled: Boolean
},
data() {
return {
inited: false
};
},
computed: {
selected() {
return this.index === this.parent.curActive;
}
},
watch: {
'parent.curActive'() {
this.inited = this.inited || this.selected;
},
title() {
this.parent.setLine();
}
},
mounted() {
if (this.slots('title')) {
this.parent.renderTitle(this.$refs.title, this.index);
}
},
render(h) {
const { slots, selected } = this;
const shouldRender = this.inited || !this.parent.lazyRender;
const Content = [shouldRender ? slots() : h()];
if (slots('title')) {
Content.push(<div ref="title">{slots('title')}</div>);
}
if (this.parent.animated) {
return (
<div
role="tabpanel"
aria-hidden={!selected}
class={bem('pane-wrapper', { inactive: !selected })}
>
<div class={bem('pane')}>{Content}</div>
</div>
);
}
return (
<div vShow={selected} role="tabpanel" class={bem('pane')}>
{Content}
</div>
);
}
});
+17
View File
@@ -0,0 +1,17 @@
@import '../style/var';
.van-tab {
&__pane {
&,
&-wrapper {
flex-shrink: 0;
box-sizing: border-box;
width: 100%;
}
&-wrapper--inactive {
height: 0;
overflow: visible;
}
}
}
@@ -0,0 +1,252 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders demo correctly 1`] = `
<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" class="van-tab"><span class="van-ellipsis">标签 2</span></div>
<div role="tab" aria-selected="true" class="van-tab van-tab--active"><span class="van-ellipsis">标签 3</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 4</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="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="">
内容 3
</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">
<div role="tablist" class="van-tabs__nav van-tabs__nav--line">
<div role="tab" aria-selected="true" class="van-tab van-tab--active" style="flex-basis: 22%;"><span class="van-ellipsis">标签 1</span></div>
<div role="tab" class="van-tab" style="flex-basis: 22%;"><span class="van-ellipsis">标签 2</span></div>
<div role="tab" class="van-tab" style="flex-basis: 22%;"><span class="van-ellipsis">标签 3</span></div>
<div role="tab" class="van-tab" style="flex-basis: 22%;"><span class="van-ellipsis">标签 4</span></div>
<div role="tab" class="van-tab" style="flex-basis: 22%;"><span class="van-ellipsis">标签 5</span></div>
<div role="tab" class="van-tab" style="flex-basis: 22%;"><span class="van-ellipsis">标签 6</span></div>
<div role="tab" class="van-tab" style="flex-basis: 22%;"><span class="van-ellipsis">标签 7</span></div>
<div role="tab" class="van-tab" style="flex-basis: 22%;"><span class="van-ellipsis">标签 8</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="">
内容 1
</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</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>
</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" aria-selected="true" class="van-tab van-tab--active"><span class="van-ellipsis">标签 1</span></div>
<div role="tab" class="van-tab van-tab--disabled"><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="">
内容 1
</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>
</div>
<div>
<div class="van-tabs van-tabs--card">
<div class="van-tabs__wrap">
<div role="tablist" class="van-tabs__nav van-tabs__nav--card">
<div role="tab" aria-selected="true" class="van-tab van-tab--active"><span class="van-ellipsis">标签 1</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 2</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 3</span></div>
</div>
</div>
<div class="van-tabs__content">
<div role="tabpanel" class="van-tab__pane" style="">
内容 1
</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>
</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" aria-selected="true" class="van-tab van-tab--active"><span class="van-ellipsis">标签 1</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 2</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="">
内容 1
</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-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" class="van-tab"><span class="van-ellipsis">标签 2</span></div>
<div role="tab" aria-selected="true" class="van-tab van-tab--active"><span class="van-ellipsis">标签 3</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 4</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="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="">
内容 3
</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-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"><div><i class="van-icon van-icon-more-o"><!----></i>标签
</div></span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis"><div><i class="van-icon van-icon-more-o"><!----></i>标签
</div></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="">
内容 1
</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-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">标签 1</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 2</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 3</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 4</span></div>
<div class="van-tabs__line" style="width: 0px; transform: translateX(0px) translateX(-50%);"></div>
</div>
</div>
<div class="van-tabs__content van-tabs__content--animated">
<div class="van-tabs__track" style="transform: translate3d(0%, 0, 0); transition-duration: 0.3s;">
<div role="tabpanel" class="van-tab__pane-wrapper">
<div class="van-tab__pane">
内容 1
</div>
</div>
<div role="tabpanel" aria-hidden="true" class="van-tab__pane-wrapper van-tab__pane-wrapper--inactive">
<div class="van-tab__pane">
<!---->
</div>
</div>
<div role="tabpanel" aria-hidden="true" class="van-tab__pane-wrapper van-tab__pane-wrapper--inactive">
<div class="van-tab__pane">
<!---->
</div>
</div>
<div role="tabpanel" aria-hidden="true" class="van-tab__pane-wrapper van-tab__pane-wrapper--inactive">
<div class="van-tab__pane">
<!---->
</div>
</div>
</div>
</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" class="van-tab"><span class="van-ellipsis">标签 2</span></div>
<div role="tab" aria-selected="true" class="van-tab van-tab--active"><span class="van-ellipsis">标签 3</span></div>
<div role="tab" class="van-tab"><span class="van-ellipsis">标签 4</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="display: none;">
<!---->
</div>
<div role="tabpanel" class="van-tab__pane" style="">
内容 3
</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
</div>
</div>
</div>
</div>
`;
@@ -0,0 +1,220 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`border props 1`] = `
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap">
<div role="tablist" class="van-tabs__nav van-tabs__nav--line">
<div class="van-tabs__line"></div>
</div>
</div>
<div class="van-tabs__content"></div>
</div>
`;
exports[`change tabs data 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" style="border-color: #f44;">
<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" style="background-color: rgb(255, 68, 68);"></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[`change tabs data 2`] = `
<div class="van-tabs van-tabs--card">
<div class="van-tabs__wrap">
<div role="tablist" class="van-tabs__nav van-tabs__nav--card" style="border-color: blue;">
<div role="tab" aria-selected="true" class="van-tab van-tab--active" style="border-color: blue; background-color: blue;"><span class="van-ellipsis">title1</span></div>
<div role="tab" class="van-tab" style="border-color: blue; color: blue;"><span class="van-ellipsis">title2</span></div>
<div role="tab" class="van-tab van-tab--disabled" style="border-color: blue;"><span class="van-ellipsis">title3</span></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[`click to switch tab 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" style="width: 0px; transform: translateX(0px) translateX(-50%);"></div>
</div>
</div>
<div class="van-tabs__content">
<div role="tabpanel" class="van-tab__pane" style="">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[`click to switch tab 2`] = `
<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">title1</span></div>
<div role="tab" class="van-tab van-tab--active" aria-selected="true"><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" style="width: 0px; transform: translateX(0px) translateX(-50%); transition-duration: 0.3s;"></div>
</div>
</div>
<div class="van-tabs__content">
<div role="tabpanel" class="van-tab__pane" style="display: none;">Text</div>
<div role="tabpanel" class="van-tab__pane" style="">Text</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
</div>
</div>
`;
exports[`lazy render 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" style="border-color: #f44;">
<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" style="background-color: rgb(255, 68, 68);"></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[`lazy render 2`] = `
<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" style="border-color: #f44;">
<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" style="background-color: rgb(255, 68, 68); width: 2px; transform: translateX(0px) translateX(-50%);"></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;">Text</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">Text</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">
<div role="tablist" class="van-tabs__nav van-tabs__nav--line" style="border-color: #f44;">Nav Left<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" style="background-color: rgb(255, 68, 68);"></div>Nav Right
</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[`swipe to switch tab 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[`swipe to switch tab 2`] = `
<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" style="display: none;">Text</div>
<div role="tabpanel" class="van-tab__pane" style="">Text</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
</div>
</div>
`;
exports[`swipe to switch tab 3`] = `
<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" style="display: none;">Text</div>
<div role="tabpanel" class="van-tab__pane" style="">Text</div>
<div role="tabpanel" class="van-tab__pane" style="display: none;">
<!---->
</div>
</div>
</div>
`;
+4
View File
@@ -0,0 +1,4 @@
import Demo from '../demo';
import demoTest from '../../../test/demo-test';
demoTest(Demo);
+147
View File
@@ -0,0 +1,147 @@
import Vue from 'vue';
import Tab from '..';
import Tabs from '../../tabs';
import { mount, later, triggerDrag } from '../../../test/utils';
Vue.use(Tab);
Vue.use(Tabs);
function createWrapper(options = {}) {
return mount({
template: `
<van-tabs
:color="color"
:type="type"
:sticky="sticky"
:line-width="lineWidth"
:lazy-render="lazyRender"
@change="onChange"
>
${options.extraTemplate || ''}
<van-tab title="title1">Text</van-tab>
<van-tab title="title2">Text</van-tab>
<van-tab title="title3" disabled>Text</van-tab>
</van-tabs>
`,
data() {
return {
color: '#f44',
type: 'line',
sticky: true,
lineWidth: 2,
lazyRender: true
};
},
...options
});
}
test('click to switch tab', async () => {
const onChange = jest.fn();
const wrapper = mount({
template: `
<van-tabs @change="onChange">
<van-tab title="title1">Text</van-tab>
<van-tab title="title2">Text</van-tab>
<van-tab title="title3" disabled>Text</van-tab>
</van-tabs>
`,
methods: {
onChange
}
});
await later();
expect(wrapper).toMatchSnapshot();
const tabs = wrapper.findAll('.van-tab');
tabs.at(1).trigger('click');
tabs.at(2).trigger('click');
await later();
expect(wrapper).toMatchSnapshot();
expect(onChange).toHaveBeenCalledTimes(1);
});
test('swipe to switch tab', async () => {
const onChange = jest.fn();
const wrapper = mount({
template: `
<van-tabs swipeable @change="onChange">
<van-tab title="title1">Text</van-tab>
<van-tab title="title2">Text</van-tab>
<van-tab title="title3" disabled>Text</van-tab>
</van-tabs>
`,
methods: {
onChange
}
});
const content = wrapper.find('.van-tabs__content');
await later();
expect(wrapper).toMatchSnapshot();
triggerDrag(content, -100, 0);
expect(wrapper).toMatchSnapshot();
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith(1, 'title2');
triggerDrag(content, -100, 0);
expect(onChange).toHaveBeenCalledTimes(1);
expect(wrapper).toMatchSnapshot();
await later();
wrapper.destroy();
});
test('change tabs data', async () => {
const wrapper = createWrapper();
await later();
expect(wrapper).toMatchSnapshot();
wrapper.setData({
swipeable: false,
sticky: false,
type: 'card',
color: 'blue'
});
await later();
expect(wrapper).toMatchSnapshot();
});
test('lazy render', async () => {
const wrapper = createWrapper();
expect(wrapper).toMatchSnapshot();
wrapper.setData({
lazyRender: false
});
await later();
expect(wrapper).toMatchSnapshot();
});
test('render nav-left & nav-right slot', async () => {
const wrapper = createWrapper({
extraTemplate: `
<template v-slot:nav-left>Nav Left</template>
<template v-slot:nav-right>Nav Right</template>
`
});
expect(wrapper).toMatchSnapshot();
});
test('border props', async () => {
const wrapper = mount(Tabs, {
propsData: {
border: false
}
});
expect(wrapper).toMatchSnapshot();
});
+206
View File
@@ -0,0 +1,206 @@
# Tab 标签页
### 引入
``` javascript
import { Tab, Tabs } from 'vant';
Vue.use(Tab).use(Tabs);
```
## 代码演示
### 基础用法
默认情况下启用第一个标签,可以通过`v-model`绑定当前激活的标签索引
```html
<van-tabs v-model="active">
<van-tab title="标签 1">内容 1</van-tab>
<van-tab title="标签 2">内容 2</van-tab>
<van-tab title="标签 3">内容 3</van-tab>
<van-tab title="标签 4">内容 4</van-tab>
</van-tabs>
```
```js
export default {
data() {
return {
active: 2
};
}
}
```
### 横向滚动
多于 4 个标签时,Tab 可以横向滚动
```html
<van-tabs>
<van-tab v-for="index in 8" :title="'标签 ' + index">
内容 {{ index }}
</van-tab>
</van-tabs>
```
### 禁用标签
设置`disabled`属性即可禁用标签。如果需要监听禁用标签的点击事件,可以在`van-tabs`上监听`disabled`事件
```html
<van-tabs @disabled="onClickDisabled">
<van-tab title="标签 1">内容 1</van-tab>
<van-tab title="标签 2" disabled>内容 2</van-tab>
<van-tab title="标签 3">内容 3</van-tab>
</van-tabs>
```
```javascript
export default {
methods: {
onClickDisabled(index, title) {
this.$toast(title + '已被禁用');
}
}
};
```
### 样式风格
`Tab`支持两种样式风格:`line`和`card`,默认为`line`样式,可以通过`type`属性修改样式风格
```html
<van-tabs type="card">
<van-tab title="标签 1">内容 1</van-tab>
<van-tab title="标签 2">内容 2</van-tab>
<van-tab title="标签 3">内容 3</van-tab>
</van-tabs>
```
### 点击事件
可以在`van-tabs`上绑定`click`事件,事件传参为标签对应的索引和标题
```html
<van-tabs @click="onClick">
<van-tab title="标签 1">内容 1</van-tab>
<van-tab title="标签 2">内容 2</van-tab>
</van-tabs>
```
```javascript
export default {
methods: {
onClick(index, title) {
this.$toast(title);
}
}
};
```
### 粘性布局
通过`sticky`属性可以开启粘性布局,粘性布局下,当 Tab 滚动到顶部时会自动吸顶
```html
<van-tabs v-model="active" sticky>
<van-tab v-for="index in 4" :title="'选项 ' + index">
内容 {{ index }}
</van-tab>
</van-tabs>
```
### 自定义标签
通过 title 插槽可以自定义标签内容
```html
<van-tabs v-model="active">
<van-tab v-for="index in 2">
<div slot="title">
<van-icon name="more-o" />选项
</div>
内容 {{ index }}
</van-tab>
</van-tabs>
```
### 切换动画
通过`animated`属性可以开启切换标签内容时的转场动画
```html
<van-tabs v-model="active" animated>
<van-tab v-for="index in 4" :title="'选项 ' + index">
内容 {{ index }}
</van-tab>
</van-tabs>
```
### 滑动切换
通过`swipeable`属性可以开启滑动切换标签页
```html
<van-tabs v-model="active" swipeable>
<van-tab v-for="index in 4" :title="'选项 ' + index">
内容 {{ index }}
</van-tab>
</van-tabs>
```
## API
### Tabs Props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|------|------|
| v-model | 当前标签的索引 | `String` `Number` | `0` | 1.0.6 |
| type | 样式类型,可选值为`card` | `String` | `line` | - |
| duration | 动画时间,单位秒 | `Number` | `0.3` | - |
| background | 标签栏背景色 | `String` | `white` | 1.6.5 |
| line-width | 底部条宽度,默认单位 px | `Number | String` | `auto` | 1.1.1 |
| line-height | 底部条高度,默认单位 px | `Number | String` | `3px` | 1.5.0 |
| color | 标签主题色 | `String` | `#f44` | 1.2.0 |
| title-active-color | 标题选中态颜色 | `String` | - | 1.6.5 |
| title-inactive-color | 标题默认态颜色 | `String` | - | 1.6.5 |
| swipe-threshold | 滚动阈值,标签数量超过多少个可滚动 | `Number` | `4` | - |
| offset-top | 粘性定位布局下与顶部的最小距离,单位 px | `Number` | `0` | 1.1.15 |
| animated | 是否开启切换标签内容时的转场动画 | `Boolean` | `false` | 1.4.5 |
| border | 是否显示标签栏外边框,仅在`type="line"`时有效 | `Boolean` | `true` | 2.0.0 |
| ellipsis | 是否省略过长的标题文字 | `Boolean` | `true` | 1.5.0 |
| sticky | 是否使用粘性定位布局 | `Boolean` | `false` | - |
| swipeable | 是否开启手势滑动切换 | `Boolean` | `false` | 1.0.0 |
| lazy-render | 是否开启标签页内容延迟渲染 | `Boolean` | `true` | 1.6.6 |
### Tab Props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|------|------|------|------|------|
| title | 标题 | `String` | - | - |
| disabled | 是否禁用标签 | `Boolean` | `false` | - |
### Tabs Slots
| 名称 | 说明 |
|------|------|
| nav-left | 标题左侧内容 |
| nav-right | 标题右侧内容 |
### Tab Slots
| 名称 | 说明 |
|------|------|
| default | 标签页内容 |
| title | 自定义标签 |
### Tabs Events
| 事件名 | 说明 | 回调参数 |
|------|------|------|
| click | 点击标签时触发 | index:标签索引,title:标题 |
| change | 当前激活的标签改变时触发 | index:标签索引,title:标题 |
| disabled | 点击被禁用的标签时触发 | index:标签索引,title:标题 |
| scroll | 滚动时触发,仅在 sticky 模式下生效 | { scrollTop: 距离顶部位置, isFixed: 是否吸顶 } |