tabControl组件的吸顶效果

最开始,还没有使用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的吸顶效果。

原文地址:https://www.cnblogs.com/ljylearnsmore/p/14208768.html