图片加载完成后,通过ref来获取组件距离父元素顶部的高度,通过监听滚动事件,把滚动y坐标和组件距离父元素顶部的距离比较,找到吸顶的临界值
暴露了问题:
(1)在better-scroll里使用position:sticky会无效,使用position:fixed定位会被better-scroll自身实现过程的tanslate给位移出去
(2)改变切换栏内容,当组件创建时会重新挂载,使得吸顶前后内容不一致
(3)当使用v-if来显示隐藏时,无法获取ref
解决方案:
(1)做两个切换栏,一个在better-scroll外,一个在内,当达到临界值时,通过v-if指令,让内部隐藏,外部显示,外部可以使用postion:fixed达到吸顶的效果
(2)通过两个ref(相同的ref后者会覆盖前者),操作组件内的当前索引属性,使得吸顶前后切换栏内容一致
(3)v-show
代码示例:
<template>
<div class='home'>
<NavBar title='购物街'/>
<TabControl :title="['流行','新款','精选']" @currentIndex='_currentIndex' ref='tabControl' :class='{fixed:tabFixed}' v-show='tabFixed'/>
<Scroll @loadMore='_loadMore' @loadRefresh='_loadRefresh' :tabOffsetTop='tabOffsetTop' @sticky='_sticky'>
//监听轮播图的图标加载完成后调用@load='_onLoad'
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item v-for='(item,index) in banners' :key='index'><img :src="item" alt="" @load='_onLoad'></van-swipe-item>
</van-swipe>
<TabControl v-show='!tabFixed' :title="['流行','新款','精选']" @currentIndex='_currentIndex' ref='tabControl2' />
</Scroll>
</div>
</template>
//tab切换
_currentIndex(index)
{
switch(index)
{
case 0:
this.currentType='pop';
break;
case 1:
this.currentType='new';
break;
default:
this.currentType='sell';
break;
}
//通过ref改变组件内部的属性,使得两个切换栏的状态一致
this.$refs.tabControl.currentIndex=index
this.$refs.tabControl2.currentIndex=index
},
//当轮播图加载完成后,获取tabs距离顶部的高度,来做吸顶效果
_onLoad()
{
this.tabOffsetTop=this.$refs.tabControl.$el.offsetTop;
},
//吸顶实现
_sticky(tabFixed)
{
this.tabFixed=tabFixed;
}
组件向外传递数据
//监听滚动事件
this.scroll.on('scroll',(e)=>{
//回到顶部按钮出现临界值
this.show=-e.y>400?true:false
//tabs的吸顶判断
if(-e.y>=(this.tabOffsetTop-50))
{
this.$emit('sticky',true)
}else{
this.$emit('sticky',false)
}
})
效果图: