[Improvement] Tab: support custom sticky offset top (#1519)

This commit is contained in:
neverland 2018-07-22 14:35:00 +08:00 committed by GitHub
parent e5f252944a
commit 004de364d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 14 deletions

View File

@ -144,6 +144,7 @@ In swipeable mode, you can switch tabs with swipe gestrue in the content
| line-width | Width of tab line (px) | `Number` | Width of active tab |
| swipe-threshold | Set swipe tabs threshold | `Number` | `4` | - |
| sticky | Whether to use sticky mode | `Boolean` | `false` |
| offset-top | Offset top when use sticky mode | `Number` | `0` |
| swipeable | Whether to switch tabs with swipe gestrue in the content | `Boolean` | `false` |
### Tab API

View File

@ -4,7 +4,7 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-tabs__wrap--content-top van-hairline--top-bottom">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div class="van-tabs__nav van-tabs__nav--line">
<div class="van-tabs__line"></div>
</div>
@ -31,7 +31,7 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-tabs__wrap--content-top van-hairline--top-bottom">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div class="van-tabs__nav van-tabs__nav--line">
<div class="van-tabs__line"></div>
</div>
@ -74,7 +74,7 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-tabs__wrap--content-top van-hairline--top-bottom">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div class="van-tabs__nav van-tabs__nav--line">
<div class="van-tabs__line"></div>
</div>
@ -101,7 +101,7 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-tabs van-tabs--card">
<div class="van-tabs__wrap van-tabs__wrap--content-top">
<div class="van-tabs__wrap">
<div class="van-tabs__nav van-tabs__nav--card">
<!---->
</div>
@ -128,7 +128,7 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-tabs__wrap--content-top van-hairline--top-bottom">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div class="van-tabs__nav van-tabs__nav--line">
<div class="van-tabs__line"></div>
</div>
@ -155,7 +155,7 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-tabs__wrap--content-top van-hairline--top-bottom">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div class="van-tabs__nav van-tabs__nav--line">
<div class="van-tabs__line"></div>
</div>
@ -182,7 +182,7 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-tabs__wrap--content-top van-hairline--top-bottom">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div class="van-tabs__nav van-tabs__nav--line">
<div class="van-tabs__line"></div>
</div>
@ -213,7 +213,7 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap van-tabs__wrap--content-top van-hairline--top-bottom">
<div class="van-tabs__wrap van-hairline--top-bottom">
<div class="van-tabs__nav van-tabs__nav--line">
<div class="van-tabs__line"></div>
</div>

View File

@ -146,6 +146,7 @@ export default {
| line-width | 底部条宽度 (px) | `Number` | 与当前标签等宽 |
| swipe-threshold | 滚动阀值,设置 Tab 超过多少个可滚动 | `Number` | `4` |
| sticky | 是否使用粘性定位布局 | `Boolean` | `false` |
| offset-top | 粘性定位布局下与顶部的最小距离 (px) | `Number` | `0` |
| swipeable | 是否可以滑动内容切换 | `Boolean` | `false` |
### Tab API

View File

@ -2,8 +2,9 @@
<div :class="b([type])">
<div
ref="wrap"
:style="wrapStyle"
:class="[
b('wrap', [position, { scrollable }]),
b('wrap', { scrollable }),
{ 'van-hairline--top-bottom': type === 'line' }
]"
>
@ -64,13 +65,17 @@ export default create({
swipeThreshold: {
type: Number,
default: 4
},
offsetTop: {
type: Number,
default: 0
}
},
data() {
return {
tabs: [],
position: 'content-top',
position: '',
curActive: null,
lineStyle: {},
events: {
@ -85,6 +90,23 @@ export default create({
// whether the nav is scrollable
scrollable() {
return this.tabs.length > this.swipeThreshold;
},
wrapStyle() {
switch (this.position) {
case 'top':
return {
top: this.offsetTop + 'px',
position: 'fixed'
};
case 'bottom':
return {
top: 'auto',
bottom: 0
};
default:
return null;
}
}
},
@ -197,15 +219,15 @@ export default create({
// adjust tab position
onScroll() {
const scrollTop = scrollUtils.getScrollTop(window);
const scrollTop = scrollUtils.getScrollTop(window) + this.offsetTop;
const elTopToPageTop = scrollUtils.getElementTop(this.$el);
const elBottomToPageTop = elTopToPageTop + this.$el.offsetHeight - this.$refs.wrap.offsetHeight;
if (scrollTop > elBottomToPageTop) {
this.position = 'content-bottom';
this.position = 'bottom';
} else if (scrollTop > elTopToPageTop) {
this.position = 'page-top';
this.position = 'top';
} else {
this.position = 'content-top';
this.position = '';
}
},