uni-app(vue3)动态获取swiper的区域高度以及通过scroll-view实现区域滚动和scroll-view的置顶功能
计算方式:
swiper高度 = page高度 - tabs高度 - search高度
具体实现:
<swiper class="swiper-box" :duration="500" @change="changeSwiper" :current="currentSwiperIndex" :style="'height:' + swiperHeight + 'px'"><swiper-item class="swiper-item"><scroll-view scroll-y="true" :show-scrollbar="false" :style="'height:' + swiperHeight + 'px'" @scrolltolower="lower" :scroll-top="scrollTop" @scroll="scroll"><Recommend :openUpdateFlag="openUpdateFlag" @closeUpdateFlag="handleDataUpdate" /></scroll-view></swiper-item></swiper></view><!-- 置顶 --><view class="topIcon" v-if="isShowArrowUpward" @click="goScrollTop"><up-icon name="arrow-upward" color="#fff" size="28"></up-icon></view>
- swiperHeight:计算swiper动态高度
- :scroll-top: 用于重置"scroll"高度
- @scroll: 获取"scroll"滚动后的信息
- @scrolltolower: 触底后自动触发,用于异步请求以加载更多数据
- :show-scrollbar: 不显示滚动条
注意: scroll-view同样需要计算区域高度
const isShowArrowUpward = ref(false); // 置顶图标
const swiperHeight = ref(0); // swiper高度
const tmpScrollHeight = ref(0); // 记录scroll临时高度
const scrollTop = ref(0); // 重置scroll高度
计算swiper的高度
// 计算swiper的高度
onMounted(() => {let headerSearchHeight,headerTabsHeight = 0;// 头部搜索height: header-containerlet headerSearchView = uni.createSelectorQuery().select('.header-container');headerSearchView.boundingClientRect((data) => {headerSearchHeight = data.height;}).exec();// 顶部tabs-height:let headerTabsView = uni.createSelectorQuery().select('.u-tabs');headerTabsView.boundingClientRect((data) => {headerTabsHeight = data.height;}).exec();// swiper-heightuni.getSystemInfo({success: (res) => {swiperHeight.value = res.windowHeight - headerSearchHeight - headerTabsHeight;}});
});
注意: 需要在dom渲染完成后(onMounted、onReady)才能获取到高度值
/*** scroll-view 是区域滚动,所以无法去监听屏幕滚动*/
const scroll = (e) => {// 记录"scroll-view"临时滚动的高度tmpScrollHeight.value = e.detail.scrollTop;if (e.detail.scrollTop > 400) {// 显示"置顶"图标 isShowArrowUpward.value = true;} else {isShowArrowUpward.value = false;}
};
scroll-view置顶(方案一: 无动画)
// scroll-view高度置顶
const goScrollTop = () => {// 解决view层不同步的问题scrollTop.value = tmpScrollHeight.value;// 强制刷新nextTick(() => {scrollTop.value = 0;});
};
scroll-view置顶(方案二: 添加过渡动画)
JavaScript 模拟平滑滚动(适用于所有平台,包括微信小程序)
const scrollDuration = 300; // 动画时长(ms)const goScrollTop = () => {// 解决view层不同步的问题scrollTop.value = tmpScrollHeight.value;const startTime = Date.now();const startTop = scrollTop.value;const distance = startTop; // 需要滚动的距离const scrollStep = () => {const currentTime = Date.now();const timeElapsed = currentTime - startTime;const progress = Math.min(timeElapsed / scrollDuration, 1); // 0~1// 使用缓动函数(如 easeOutQuad)const easeProgress = 1 - Math.pow(1 - progress, 2);scrollTop.value = startTop - distance * easeProgress;if (timeElapsed < scrollDuration) {requestAnimationFrame(scrollStep);} else {// 强制刷新nextTick(() => {scrollTop.value = 0; // 确保最终位置准确});}};requestAnimationFrame(scrollStep);
};
.topIcon {position: fixed;bottom: 120rpx;right: 30rpx;width: 44rpx;height: 44rpx;background-color: rgb(0, 0, 0, 0.5);border-radius: 40rpx;display: flex;justify-content: center;align-items: center;
}