关于uniapp的scroll-view的滚动问题

有一个疑惑很久的问题想请教一下大家。我用uniapp写了一个页面,顶部一个topBar,然后下面是一个滚动视图scroll-view。topBar与scroll-view是同级别分开的两个元素,所以我认为滚动应该不会影响topBar才对,我的需求也是topBar固定,scroll-view滚动时不会顶着topBar一起滚动。但我运行之后,scroll-view滚动后,topBar也被滚上去了,请问大家该怎么解决呢?
代码如下:

<template>
    <view class="index">
        <view class="topBar">
            <view :class="topBarIndex==0?'topBar-item topBar-selected':'topBar-item'" @tap="changeTopBarIndex(0)">
                <text class="topBar-font">文章</text>
            </view>
            <view :class="topBarIndex==1?'topBar-item topBar-selected':'topBar-item'" @tap="changeTopBarIndex(1)">
                <text class="topBar-font">关注</text>
            </view>
            <view :class="topBarIndex==2?'topBar-item topBar-selected':'topBar-item'" @tap="changeTopBarIndex(2)">
                <text class="topBar-font">推荐</text>
            </view>
            <view :class="topBarIndex==3?'topBar-item topBar-selected':'topBar-item'" @tap="changeTopBarIndex(3)">
                <text class="topBar-font">热榜</text>
            </view>
        </view>
        <scroll-view scroll-y="true" >
            <swiper>
                <swiper-item>
                        <view class="all-categories">
                            <AnswerList></AnswerList>
                        </view>
                </swiper-item>
            </swiper>
        </scroll-view>
    </view>
</template>

<script>
    import AnswerList from '@/components/index/AnswerList.vue'
    export default {
        components: {
            AnswerList
        },
        data() {
            return {
                topBarIndex: 2
            }
        },
        onLoad() {

        },
        methods: {
            changeTopBarIndex(index) {
                if(this.topBarIndex === index) {
                    return;
                }
                this.topBarIndex = index;
            }
        }
    }
</script>

<style scoped>    
    .topBar {
        display: flex;
        justify-content: center;
        gap: 15px;
    }
    
    swiper {
        height: 2000rpx;
    }
    
    .all-categories {
        height: 2500rpx;
        background-color: #f6f6f6;
    }
</style>


运行截图如下:

img

滚动之后,topBar被顶上去了:

img

引用 皆我百晓生 小程序回复内容作答:
根据你的代码,可以看出滚动导致topBar也跟着滚动的原因是因为在滚动视图scroll-view组件上没有设置fixed定位,所以滚动时会顶着topBar一起滚动。解决方法是给topBar添加fixed定位,并设置顶部的偏移量,来固定topBar在页面顶部。

修改代码如下:

<template>
    <view class="index">
        <view class="topBar" :style="topBarIndex!=0?`top:${topBarOffset}px`:''">
            ... // 省略其他代码
        </view>
        <scroll-view scroll-y="true">
            ...
        </scroll-view>
    </view>
</template>

同时,在data中添加一个topBarOffset的数据,用于设置顶部偏移量。修改代码如下:

<script>
    ...
    data() {
        return {
            topBarIndex: 2,
            topBarOffset: 0
        }
    },
    ...
</script>

最后,在methods中添加一个监听页面滚动的方法,根据页面滚动的距离动态更新topBarOffset的值。修改代码如下:

<script>
    ...
    methods: {
        ...
        onPageScroll(e) {
            this.topBarOffset = e.scrollTop;
        }
    },
    onPageScroll(e) {
        this.onPageScroll(e);
    }
</script>

这样修改之后,滚动视图scroll-view滚动时,topBar会固定在页面顶部,不会跟着滚动。

需要给scroll设置高度

<template>
    <view class="index">
        <view class="topBar">
            <view :class="topBarIndex==0?'topBar-item topBar-selected':'topBar-item'" @tap="changeTopBarIndex(0)">
                <text class="topBar-font">文章</text>
            </view>
            <view :class="topBarIndex==1?'topBar-item topBar-selected':'topBar-item'" @tap="changeTopBarIndex(1)">
                <text class="topBar-font">关注</text>
            </view>
            <view :class="topBarIndex==2?'topBar-item topBar-selected':'topBar-item'" @tap="changeTopBarIndex(2)">
                <text class="topBar-font">推荐</text>
            </view>
            <view :class="topBarIndex==3?'topBar-item topBar-selected':'topBar-item'" @tap="changeTopBarIndex(3)">
                <text class="topBar-font">热榜</text>
            </view>
        </view>
        <view class='scroll-box'>
            <scroll-view :scroll-y="true" style='height: 100%;'>
                <swiper>
                    <swiper-item>
                            <view class="all-categories">
                                <AnswerList></AnswerList>
                            </view>
                    </swiper-item>
                </swiper>
            </scroll-view>
        </view>
    </view>
</template>
 
<script>
    import AnswerList from '@/components/index/AnswerList.vue'
    export default {
        components: {
            AnswerList
        },
        data() {
            return {
                topBarIndex: 2
            }
        },
        onLoad() {
 
        },
        methods: {
            changeTopBarIndex(index) {
                if(this.topBarIndex === index) {
                    return;
                }
                this.topBarIndex = index;
            }
        }
    }
</script>
 
<style scoped>    
    .index {
        display: flex;
        flex-direction: column;
    }

    .topBar {
        display: flex;
        justify-content: center;
        gap: 15px;
    }
    
    .scroll-box {
        flex: 1;
        overflow: hidden;
    }
    
    swiper {
        height: 2000rpx;
    }
    
    .all-categories {
        height: 2500rpx;
        background-color: #f6f6f6;
    }
</style>