先在data()里面先默认该属性为0
tabOffsetTop:0,
然后
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick" ref="tabControl2"
></tab-control>
在mouted()里面
// 获取tabControl的offsetTop
this.$refs.tabControl2.offsetTop;
但是组件有没有一个属性叫offsetTop呢?我们打印一下:

发现它并没有这个属性。
所以我们应该去拿组件的元素,所有的属性都有一个$el属性,用于获取组将中的元素的
console.log(this.$refs.tabControl2.$el.offsetTop);
最终的结果是

但是这个值一看就我们想象中的值有出入
原因也是图片的问题,图片并没有加载完,所以我们获取的值就比较小。此时我们就要想办法去监听这个图片加载完成,加载完成以后再获取offsetTop。
经过测试,发现轮播图加载完成以后,我们拿到的offsetTop就是一个比较正确的值。所以我们直接监听轮播图加载。
我们直接找到轮播图的存放位置,在HomeSwiper.vue的img里
<img :src="item.image" alt="" @load="imageLoad">
methods:{
imageLoad(){
this.$emit('swiperImageLoad')
}
}
在Home.vue里面有
<home-swiper :banners="banners" @swiperImageLoad="swiperImageLoad"></home-swiper>
swiperImageLoad(){
this.tabOffsetTop = this.$refs.tabControl2.$el.offsetTop;
}
此时我们在控制台打印offsetTop

但是此时我们因为有4张图片所以打印输出4次,但是我们只需要一次就可以。
在HomeSwiper.vue中
data(){
return{
isLoad:false
}
methods:{
imageLoad(){
if(!this.isLoad)
this.$emit('swiperImageLoad')
this.isLoad=true
}
}
只发出一次事件
在Home.vue的data中,默认不吸顶
isTabFixed:false
在methods中的contentScroll方法里面,决定是否吸顶
contentScroll(position) {
// console.log(position);
//判断BackTop是否显示
this.isShowBackTop = (-position.y) > 1000
//决定tabControl是否吸顶(position:fixed)
this.isTabFixed= (-position.y)>this.tabOffsetTop
},
这里的offsetTop指的是图片加载完成,加载完成以后再获取的offsetTop,也就是544这个值,之后我们在动态的绑定样式。
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick" ref="tabControl2"
:class="{fixed:isTabFixed}"
然后对应的css样式如下:
.fixed{
position: fixed;
left: 0;
right: 0;
top: 44px;
}
我们来看一下效果:

我们会发现这个效果并没有达到预期。
1、我们会发现它突然往上面走了一下,原因是什么?
因为原来在我们的布局上面,这个tabControl把内容都往下压了压,然后tabControl脱标了以后,下面的东西都会往上走tabControl的高度,所以会突然往上升了升
2、我们会发现tabControl不见了
我们发现在滚动的过程中,它的fixed属性是在的,但是就是没有显示。
解决方案:
在Home.vue中将tabControl复制一份到scroll标签上面
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick" ref="tabControl2"
></tab-control>
<scroll class="content" ref="scroll" :probe-type="3"
@scroll="contentScroll"
:pull-up-load="true"
@pullingUp="loadMore"
>
<home-swiper :banners="banners" @swiperImageLoad="swiperImageLoad"></home-swiper>
<recommend-view :recommends="recommends"></recommend-view>
<feature-view></feature-view>
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick" ref="tabControl2"
></tab-control>
<goods-list :goods="showGoods"></goods-list>
</scroll>
我们可以看到结果如下:

我们发现tabControl到了navbar下面,因为这个navbar设置了position:fixed属性,已经脱离了标准流。之前设置fixed是因为使用的是原生的滚动,为了使导航不跟着一起滚动。现在我们用来better-scroll,它本身就可以实现局部滚动,所以在这种情况下,我们的这个navbar设置了position:fixed属性就可以不用要了。效果如下:

我们添加一个class属性
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick" ref="tabControl2"
class="tab-control"
></tab-control>
.tab-control {
position: relative;
z-index: 9;
}

我们可以这么做,一旦我们向上滚动的时候,当我滚到两个tabControl重合的时候,就让最上面的那个tabControl显示出来,一旦到了下面的时候,就让它消失,也就是
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick" ref="tabControl2"
class="tab-control" v-show="isTabFixed"
></tab-control>
在这个标签里面默认它是消失的,上述标签中多了一个v-show属性
v-show="isTabFixed"
结果如下:

但是我们有发现了下述问题:

上面的流行、新款、精选没有保持一致。而我们的currentIndex是记录当前谁被选中,我们将ref重新赋值,便于区分
<tab-control class="tab-control" :titles="['流行','新款','精选']" @tabClick="tabClick"
ref="tabControl2" v-show="isTabFixed"></tab-control>
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick" ref="tabControl2"
></tab-control>
我们在方法里面找到tabClick()监听点击里面
this.$refs.tabControl1.currentIndex=index
this.$refs.tabControl2.currentIndex=index
并将之前所用过的tabControl重新进行修改,我们来看一下最终的结果:

必须知道滚动到多少时,开始有吸顶效果,这个时候就需要获取tabControl的offsetTop
但是,如果直接在mounted中获取tabControl的offsetTop,那么值是不正确.
如何获取正确的值了?
。监听HomeSwiper中img的加载完成
。加载完成后,发出事件,在Home.vue中,获取正确的值.
。补充:
。注意:这里不进行多次调用和debounce的区别