最开始,还没有使用better-scroll插件的时候,直接在class中设定了一定的position为sticky,设置一定的top达成了效果。但是,使用better-scroll组件后,这些属性就没有用了。那么,为了还能达成这个效果,按照以下方法。
在实现这个效果之前,必须先知道滚动到多少位置时,开始有吸顶效果。
首先我先尝试了,在home.vue中的mounted里面直接
console.log(this.$refs.tabcontrol.$el.offsetTop);
但是这个打印出来的结果明显是不正确的,因为在mounted里面拿到的是,很多图片还没有加载完毕的,因此这里所得出来的值是不正确的。经过测试,发现tabcontrol上面的三个组件中,轮播图的加载是最为影响的,因此我就监听homeswiper中的图片加载,使用@load来完成。加载完成后,发出事件后,再home.vue中获取正确的值。
homeswiper.vue中:
<template> <swiper> <swiperitem v-for="(item,index) in banners" :key="index"> <a :href="item.link"> <img :src="item.image" @load="imageload"> </a> </swiperitem> </swiper> </template> <script> import swiperitem from "../../../src/components/common/swiper/swiperitem"; import swiper from "../../../src/components/common/swiper/swiper"; export default { name: "homeswiper", props:{ banners:{ type:Array, default(){ return [] } } }, components:{swiperitem,swiper}, data(){ return{ isload:false } }, methods:{ imageload(){ // console.log("111"); if (!this.isload){ this.$emit("swiperimageload") this.isload = true } } } } </script> <style scoped> </style>
在home.vue中:
<tabcontrol :titles="['流行','新款','精选']" @tabclick="tabclick"
ref="tabcontrol2"> </tabcontrol>
<homeswiper :banners="banners" @swiperimageload="swiperimageload"></homeswiper> methods:{ swiperimageload(){ // console.log(this.$refs.tabcontrol.$el.offsetTop); this.tabOffsetTop = this.$refs.tabcontrol.$el.offsetTop } }
data(){ return{ tabOffsetTop:0 } }
解析:
首先,现在homeswiper中对其图片进行监听,并定义一个方法为imageload。这个方法中,将swiperimageload发出。由于,homeswiper与home为子与父组件关系。然后,在home中,先设置taboffsetTop为0,之后再在swiperimageload当中将其赋值给tabOffsetTop。
在这里,我为了不让homeswiper多次发出事件,我在homeswiper中的data加了一个isload,之后我使用isload的变量进行状态的记录。
之后,我们就可以在之前做backtop组件中,所使用到的contentscroll方法中,将当前position与tabOffsetTop进行一个判断。这边我们可以再回顾下原来在scroll中写的:
mounted(){ //1.创建BScroll对象 this.scroll = new BScroll(this.$refs.wrapper,{ click:true, probeType:this.probeType, pullUpLoad:this.pullUpLoad //监听滚动到底部 }) // this.scroll.scrollTo(0,0) //2.监听滚动的位置 this.scroll.on("scroll",(position)=>{ // console.log(position); this.$emit("scroll",position) }) }
在home.vue中写的:
<scroll class="content" ref="scroll" :probe-type="3" @scroll="contentscroll" :pull-up-load="true" @pullingUp="loadmore">
data(){ return{ banners:[], recommends:[], goods:{ 'pop':{page:0,list:[]}, 'new':{page:0,list:[]}, 'sell':{page:0,list:[]} }, currenttype:'pop', isshow:false, tabOffsetTop:0, istabfixed:false } }
contentscroll(position){ //1.判断backtop是否显示 this.isshow= (-position.y) > 1000 //2.决定tabcontrol是否吸顶 this.istabfixed = (-position.y) > this.tabOffsetTop }
最开始,我是按照上述写之后,直接在tabcontrol组件中利用istabfixed的值,然后用v-bind:class="{active:istabfixed}",再在active中设置,position为fixed,以及一定的top值,但是实际执行后,发现,在此处position为fixed时,并不生效。显示出来的结果为,下面的商品内容会往上移,且tabcontrol随着滚动会滑出去。达不到吸顶效果,因此为了达到效果,我们在上面多复制了一份PlaceHoldertabcontrol组件对象,利用他来实现停留效果。当用户滚动到一定位置时,PlaceHoldertabcontrol显示出来,而当用户未滚动到一定位置时,被隐藏起来。
<template> <div class="homie"> <navbar class="home-nav"><div slot="center">购物街</div> </navbar> <tabcontrol :titles="['流行','新款','精选']" @tabclick="tabclick" ref="tabcontrol1" class="tab" v-show="istabfixed"> </tabcontrol> <scroll class="content" ref="scroll" :probe-type="3" @scroll="contentscroll" :pull-up-load="true" @pullingUp="loadmore"> <homeswiper :banners="banners" @swiperimageload="swiperimageload"></homeswiper> <reco :recommends="recommends"></reco> <featureview></featureview> <tabcontrol :titles="['流行','新款','精选']" @tabclick="tabclick" ref="tabcontrol2"> </tabcontrol> <goodslist :goods="showgoods"></goodslist> </scroll> </div> </template>
contentscroll(position){ this.isshow= (-position.y) > 1000 this.istabfixed = (-position.y) > this.tabOffsetTop }
tabclick(index){ switch (index){ case 0: this.currenttype ="pop" break case 1: this.currenttype = 'new' break case 2: this.currenttype="sell" break } this.$refs.tabcontrol1.currentIndex = index; this.$refs.tabcontrol2.currentIndex = index; }
这样的设置为,于第一个tabcontrol中加一个v-show,当位置的绝对值大于tabOffsetTop时,istabfixed为true,而使得第一个tabcontrol显示出来。且为了保持数据一致,设置两个tabcontrol值,之后便在tabclick方法中,将index赋值于它们,最后设置下,第一个tabcontrol的样式。
.tab{ position: relative; z-index: 9; }
这样便实现了tabcontrol的吸顶效果。