Files
gym-manage/gym-manage-uniapp/pages/index/index.vue
T
2026-06-11 14:26:50 +08:00

214 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 水波纹背景 - 顶层显示 -->
<!-- <view class="bg-wrapper">
<image src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/wave_top.png" mode="widthFix" class="wave-bg wave-top" />
<image src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/wave_bottom.png" mode="widthFix" class="wave-bg wave-bottom" />
</view> -->
<!-- 固定白色块滚动时显示 -->
<view class="hand" :style="{height : handHeight + 'rpx'}" v-show="isShow"></view>
<!-- 滚动内容区域 -->
<scroll-view
scroll-y
refresher-enabled
:refresher-triggered="isRefreshing"
refresher-default-style="none"
@refresherrefresh="onRefresh"
@scroll="handleScroll"
class="scroll-container"
>
<!-- 主内容 -->
<view class="home-page">
<HomeSkeleton v-if="loading" />
<template v-else>
<BannerSwiper />
<QuickEntry />
<RecommendCourses />
<TodayRecommend />
<view class="bottom-placeholder"></view>
</template>
</view>
</scroll-view>
<!-- TabBar 固定在底部 -->
<view class="tabbar-fixed">
<TabBar />
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import BannerSwiper from '@/components/index/BannerSwiper.vue'
import QuickEntry from '@/components/index/QuickEntry.vue'
import RecommendCourses from '@/components/index/RecommendCourses.vue'
import TodayRecommend from '@/components/index/TodayRecommend.vue'
import TabBar from '@/components/TabBar.vue'
import HomeSkeleton from '@/components/Skeleton/HomeSkeleton.vue'
const loading = ref(true)
const isShow = ref(false)
const handHeight = ref(0)
const scrollDistance = ref(0)
const isRefreshing = ref(false)
// 获取可视窗口高度
const windowHeight = ref(0)
// 获取整个滚动内容的高度
const scrollContentHeight = ref(0)
// 滚动监听
const handleScroll = (e) => {
const distance = e.detail.scrollTop
scrollDistance.value = distance
// 获取滚动容器的高度(可视区域高度)
const scrollViewHeight = e.detail.scrollHeight
scrollContentHeight.value = scrollViewHeight
// 计算滚动百分比
// 滚动百分比 = 当前滚动距离 / (内容总高度 - 可视区域高度) * 100
const maxScrollDistance = scrollContentHeight.value - windowHeight.value
let scrollPercent = 0
if (maxScrollDistance > 0) {
scrollPercent = (distance / maxScrollDistance) * 100
}
console.log(`滚动距离: ${distance}, 滚动百分比: ${scrollPercent.toFixed(2)}%`)
// 当滚动超过 10% 时显示白色块(你可以调整这个百分比)
const SHOW_THRESHOLD = 40 // 10% 的阈值,可以根据需要调整
isShow.value = scrollPercent > SHOW_THRESHOLD
}
// 下拉刷新处理
const onRefresh = async () => {
console.log('开始下拉刷新')
isRefreshing.value = true
try {
await refreshData()
isRefreshing.value = false
uni.showToast({
title: '刷新成功',
icon: 'success'
})
} catch (error) {
console.error('刷新失败', error)
isRefreshing.value = false
uni.showToast({
title: '刷新失败',
icon: 'error'
})
}
}
// 刷新数据
const refreshData = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('数据已刷新')
resolve()
}, 1500)
})
}
onMounted(() => {
setTimeout(() => {
loading.value = false
}, 1500)
// 获取胶囊按钮高度
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
const navTotalHeight = menuButtonInfo.top + menuButtonInfo.height
handHeight.value = navTotalHeight * 2.5
// 获取可视窗口高度
uni.getSystemInfo({
success: (res) => {
windowHeight.value = res.windowHeight
console.log('可视窗口高度:', windowHeight.value)
}
})
// 延迟获取滚动内容高度(确保DOM已渲染)
setTimeout(() => {
const query = uni.createSelectorQuery().in(this)
query.select('.home-page').boundingClientRect(data => {
if (data) {
scrollContentHeight.value = data.height
console.log('内容总高度:', scrollContentHeight.value)
}
}).exec()
}, 500)
})
</script>
<style lang="scss" scoped>
/* 背景包装器 - 固定在最底层 */
.bg-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
pointer-events: none;
}
.wave-bg {
position: fixed;
left: 0;
width: 100%;
pointer-events: none;
opacity: 0.6;
}
.wave-top {
top: 0;
opacity: 0.5;
}
.wave-bottom {
bottom: 100rpx;
opacity: 0.35;
}
/* 滚动容器 */
.scroll-container {
position: relative;
z-index: 1;
height: 100vh;
width: 100%;
}
/* 主内容区域 */
.home-page {
min-height: 100vh;
padding-bottom: 160rpx;
}
/* 固定白色块 */
.hand {
position: fixed;
top: 0;
left: 0;
z-index: 100;
background-color: white;
width: 100%;
}
/* 固定 TabBar */
.tabbar-fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
background-color: transparent;
}
.bottom-placeholder {
height: 120rpx;
}
</style>