[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 | | line-width | Width of tab line (px) | `Number` | Width of active tab |
| swipe-threshold | Set swipe tabs threshold | `Number` | `4` | - | | swipe-threshold | Set swipe tabs threshold | `Number` | `4` | - |
| sticky | Whether to use sticky mode | `Boolean` | `false` | | 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` | | swipeable | Whether to switch tabs with swipe gestrue in the content | `Boolean` | `false` |
### Tab API ### Tab API

View File

@ -4,7 +4,7 @@ exports[`renders demo correctly 1`] = `
<div> <div>
<div> <div>
<div class="van-tabs van-tabs--line"> <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__nav van-tabs__nav--line">
<div class="van-tabs__line"></div> <div class="van-tabs__line"></div>
</div> </div>
@ -31,7 +31,7 @@ exports[`renders demo correctly 1`] = `
</div> </div>
<div> <div>
<div class="van-tabs van-tabs--line"> <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__nav van-tabs__nav--line">
<div class="van-tabs__line"></div> <div class="van-tabs__line"></div>
</div> </div>
@ -74,7 +74,7 @@ exports[`renders demo correctly 1`] = `
</div> </div>
<div> <div>
<div class="van-tabs van-tabs--line"> <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__nav van-tabs__nav--line">
<div class="van-tabs__line"></div> <div class="van-tabs__line"></div>
</div> </div>
@ -101,7 +101,7 @@ exports[`renders demo correctly 1`] = `
</div> </div>
<div> <div>
<div class="van-tabs van-tabs--card"> <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 class="van-tabs__nav van-tabs__nav--card">
<!----> <!---->
</div> </div>
@ -128,7 +128,7 @@ exports[`renders demo correctly 1`] = `
</div> </div>
<div> <div>
<div class="van-tabs van-tabs--line"> <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__nav van-tabs__nav--line">
<div class="van-tabs__line"></div> <div class="van-tabs__line"></div>
</div> </div>
@ -155,7 +155,7 @@ exports[`renders demo correctly 1`] = `
</div> </div>
<div> <div>
<div class="van-tabs van-tabs--line"> <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__nav van-tabs__nav--line">
<div class="van-tabs__line"></div> <div class="van-tabs__line"></div>
</div> </div>
@ -182,7 +182,7 @@ exports[`renders demo correctly 1`] = `
</div> </div>
<div> <div>
<div class="van-tabs van-tabs--line"> <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__nav van-tabs__nav--line">
<div class="van-tabs__line"></div> <div class="van-tabs__line"></div>
</div> </div>
@ -213,7 +213,7 @@ exports[`renders demo correctly 1`] = `
</div> </div>
<div> <div>
<div class="van-tabs van-tabs--line"> <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__nav van-tabs__nav--line">
<div class="van-tabs__line"></div> <div class="van-tabs__line"></div>
</div> </div>

View File

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

View File

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