tabbar适配安卓端
This commit is contained in:
+56
-50
@@ -3,75 +3,81 @@
|
|||||||
<GlobalLoading />
|
<GlobalLoading />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import GlobalLoading from '@/components/global/GlobalLoading.vue'
|
import GlobalLoading from '@/components/global/GlobalLoading.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
GlobalLoading
|
||||||
|
},
|
||||||
onLaunch: function() {
|
onLaunch: function() {
|
||||||
console.log('App Launch')
|
console.log('App Launch')
|
||||||
this.preloadTabData()
|
this.preloadTabData()
|
||||||
},
|
},
|
||||||
onShow: function() {
|
onShow: function() {
|
||||||
console.log('App Show')
|
console.log('App Show')
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
this.hideNativeTabBar()
|
||||||
|
// #endif
|
||||||
},
|
},
|
||||||
onHide: function() {
|
onHide: function() {
|
||||||
console.log('App Hide')
|
console.log('App Hide')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 隐藏原生 TabBar - 这里是核心修复
|
||||||
|
hideNativeTabBar() {
|
||||||
|
// 尝试多次执行,确保执行成功
|
||||||
|
const tryHide = (times = 0) => {
|
||||||
|
if (times > 10) return // 最多尝试10次
|
||||||
|
|
||||||
|
uni.hideTabBar({
|
||||||
|
animation: false,
|
||||||
|
success: () => {
|
||||||
|
console.log('✅ 原生TabBar隐藏成功')
|
||||||
|
// 强制 CSS 覆盖(双重保险)
|
||||||
|
this.forceCSSHide()
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log(`❌ 第${times+1}次隐藏失败,1秒后重试`, err)
|
||||||
|
setTimeout(() => tryHide(times + 1), 1000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 延迟 300ms 执行,确保页面挂载完成
|
||||||
|
setTimeout(() => tryHide(), 300)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 强制 CSS 覆盖(最终保险)
|
||||||
|
forceCSSHide() {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
const style = document.createElement('style')
|
||||||
|
style.innerHTML = `
|
||||||
|
uni-tabbar,
|
||||||
|
uni-tabbar .uni-tabbar,
|
||||||
|
.uni-tabbar,
|
||||||
|
uni-tabbar > .uni-tabbar,
|
||||||
|
[class*="uni-tabbar"] {
|
||||||
|
display: none !important;
|
||||||
|
height: 0 !important;
|
||||||
|
opacity: 0 !important;
|
||||||
|
visibility: hidden !important;
|
||||||
|
pointer-events: none !important;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
document.head.appendChild(style)
|
||||||
|
console.log('✅ CSS 强制覆盖已注入')
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
// 预加载所有 Tab 页面的核心数据
|
// 预加载所有 Tab 页面的核心数据
|
||||||
preloadTabData() {
|
preloadTabData() {
|
||||||
// 延迟执行,不阻塞首屏
|
// 延迟执行,不阻塞首屏
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 预加载课程数据
|
// 预加载课程数据等...
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
// 小程序端预请求数据
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// 预加载训练数据
|
|
||||||
|
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import 'common/style/base.css';
|
|
||||||
|
|
||||||
/* 全局骨架屏样式 */
|
|
||||||
.skeleton {
|
|
||||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
|
||||||
background-size: 200% 100%;
|
|
||||||
animation: skeleton-loading 1.5s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes skeleton-loading {
|
|
||||||
0% { background-position: 200% 0; }
|
|
||||||
100% { background-position: -200% 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 页面切换动画 */
|
|
||||||
.page-enter-active,
|
|
||||||
.page-leave-active {
|
|
||||||
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-enter-from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(30rpx);
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(-30rpx);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-container {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
max-width: 430px;
|
|
||||||
margin: 0 auto;
|
|
||||||
background-color: var(--bg-light);
|
|
||||||
position: relative;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<!-- components/TabBar.vue -->
|
<!-- components/TabBar.vue -->
|
||||||
<template>
|
<template>
|
||||||
<view v-if="shouldShowTabBar" class="tab-bar">
|
<view v-if="shouldShowTabBar" class="tab-bar-wrapper">
|
||||||
|
<view class="tab-bar">
|
||||||
<view
|
<view
|
||||||
v-for="(tab, index) in tabs"
|
v-for="(tab, index) in tabs"
|
||||||
:key="tab.path"
|
:key="tab.path"
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
<text class="tab-label">{{ tab.label }}</text>
|
<text class="tab-label">{{ tab.label }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -98,15 +100,22 @@ function checkShouldShow() {
|
|||||||
|
|
||||||
let routeWatcher = null
|
let routeWatcher = null
|
||||||
let appRouteCallback = null
|
let appRouteCallback = null
|
||||||
|
let isNavigating = false
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
syncActiveState()
|
syncActiveState()
|
||||||
checkShouldShow()
|
checkShouldShow()
|
||||||
// #ifdef APP-PLUS
|
// #ifndef MP-WEIXIN
|
||||||
|
// H5和其他平台使用轮询监听路由变化
|
||||||
routeWatcher = setInterval(() => {
|
routeWatcher = setInterval(() => {
|
||||||
syncActiveState()
|
// 导航期间不更新状态,避免覆盖用户点击的索引
|
||||||
|
if (isNavigating) return
|
||||||
|
const newIndex = getActiveIndexFromRoute()
|
||||||
|
if (newIndex !== currentActiveIndex.value) {
|
||||||
|
currentActiveIndex.value = newIndex
|
||||||
|
}
|
||||||
checkShouldShow()
|
checkShouldShow()
|
||||||
}, 300)
|
}, 200)
|
||||||
// #endif
|
// #endif
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
if (typeof uni.onAppRoute === 'function') {
|
if (typeof uni.onAppRoute === 'function') {
|
||||||
@@ -122,12 +131,17 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
// #ifdef APP-PLUS
|
// #ifndef MP-WEIXIN
|
||||||
if (routeWatcher) { clearInterval(routeWatcher) }
|
// H5和其他平台清理定时器
|
||||||
|
if (routeWatcher) {
|
||||||
|
clearInterval(routeWatcher)
|
||||||
|
routeWatcher = null
|
||||||
|
}
|
||||||
// #endif
|
// #endif
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
if (appRouteCallback && typeof uni.offAppRoute === 'function') {
|
if (appRouteCallback && typeof uni.offAppRoute === 'function') {
|
||||||
uni.offAppRoute(appRouteCallback)
|
uni.offAppRoute(appRouteCallback)
|
||||||
|
appRouteCallback = null
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
})
|
})
|
||||||
@@ -184,9 +198,12 @@ function onTabTap(index) {
|
|||||||
const currentPath = TAB_ROUTES[currentActiveIndex.value]
|
const currentPath = TAB_ROUTES[currentActiveIndex.value]
|
||||||
if (targetPath === currentPath) return
|
if (targetPath === currentPath) return
|
||||||
console.log('Tab 点击:', index, targetPath)
|
console.log('Tab 点击:', index, targetPath)
|
||||||
|
// 立即更新状态
|
||||||
currentActiveIndex.value = index
|
currentActiveIndex.value = index
|
||||||
emit('update:active', index)
|
emit('update:active', index)
|
||||||
emit('tab-change', index)
|
emit('tab-change', index)
|
||||||
|
// 设置导航标志,阻止轮询覆盖状态
|
||||||
|
isNavigating = true
|
||||||
let timer = setTimeout(() => {
|
let timer = setTimeout(() => {
|
||||||
uni.showLoading({ title: '加载中...', mask: true })
|
uni.showLoading({ title: '加载中...', mask: true })
|
||||||
}, 50)
|
}, 50)
|
||||||
@@ -203,7 +220,10 @@ function onTabTap(index) {
|
|||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
isSwitching = false
|
isSwitching = false
|
||||||
|
isNavigating = false
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
syncActiveState()
|
syncActiveState()
|
||||||
|
// #endif
|
||||||
checkShouldShow()
|
checkShouldShow()
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
@@ -215,11 +235,21 @@ function onTabTap(index) {
|
|||||||
// 引入字体图标 CSS(定义 @font-face)
|
// 引入字体图标 CSS(定义 @font-face)
|
||||||
@import '/common/style/tabbar_icon/tabbar.css';
|
@import '/common/style/tabbar_icon/tabbar.css';
|
||||||
|
|
||||||
.tab-bar {
|
// 固定容器 - 确保TabBar始终在屏幕底部
|
||||||
|
.tab-bar-wrapper {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-bar-wrapper .tab-bar {
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-bar {
|
||||||
height: 120rpx;
|
height: 120rpx;
|
||||||
background: white;
|
background: white;
|
||||||
backdrop-filter: blur(24px);
|
backdrop-filter: blur(24px);
|
||||||
@@ -231,7 +261,14 @@ function onTabTap(index) {
|
|||||||
padding-bottom: env(safe-area-inset-bottom);
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
box-shadow: 0 -4rpx 24rpx var(--tabbar-shadow);
|
box-shadow: 0 -4rpx 24rpx var(--tabbar-shadow);
|
||||||
border-radius: 32rpx 32rpx 0 0;
|
border-radius: 32rpx 32rpx 0 0;
|
||||||
z-index: 999;
|
/* 防闪烁优化 */
|
||||||
|
transform: translateZ(0);
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
|
will-change: transform;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
perspective: 1000;
|
||||||
|
-webkit-perspective: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-item {
|
.tab-item {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name" : "gym-manage-uniapp",
|
"name" : "活氧舱",
|
||||||
"appid" : "__UNI__1F1874C",
|
"appid" : "__UNI__52E2F0D",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "1.0.0",
|
"versionName" : "1.0.0",
|
||||||
"versionCode" : "100",
|
"versionCode" : "100",
|
||||||
@@ -41,7 +41,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
/* ios打包配置 */
|
/* ios打包配置 */
|
||||||
"ios" : {},
|
"ios" : {
|
||||||
|
"dSYMs" : false
|
||||||
|
},
|
||||||
/* SDK配置 */
|
/* SDK配置 */
|
||||||
"sdkConfigs" : {}
|
"sdkConfigs" : {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,7 +284,7 @@
|
|||||||
},
|
},
|
||||||
"uniIdRouter": {},
|
"uniIdRouter": {},
|
||||||
"tabBar": {
|
"tabBar": {
|
||||||
"custom": true, // 启用自定义 tabBar
|
"custom": true,
|
||||||
"list": [
|
"list": [
|
||||||
{ "pagePath": "pages/index/index", "text": "首页" },
|
{ "pagePath": "pages/index/index", "text": "首页" },
|
||||||
{ "pagePath": "pages/course/index", "text": "课程" },
|
{ "pagePath": "pages/course/index", "text": "课程" },
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<!-- pages/course/index.vue -->
|
<!-- pages/course/index.vue -->
|
||||||
<template>
|
<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" />
|
<scroll-view scroll-y="false" class="scroll-container">
|
||||||
<image src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/wave_bottom.png" mode="widthFix" class="wave-bg wave-bottom" />
|
|
||||||
</view> -->
|
|
||||||
<view class="tab-page">
|
<view class="tab-page">
|
||||||
<view class="tab-page__header">
|
<view class="tab-page__header">
|
||||||
<text class="tab-page__title">课程</text>
|
<text class="tab-page__title">课程</text>
|
||||||
@@ -34,7 +32,12 @@
|
|||||||
|
|
||||||
<view class="bottom-placeholder"></view>
|
<view class="bottom-placeholder"></view>
|
||||||
</view>
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- 固定 TabBar -->
|
||||||
|
<view class="tabbar-fixed">
|
||||||
<TabBar @update:active="handleTabActive" />
|
<TabBar @update:active="handleTabActive" />
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -128,34 +131,6 @@ function goMyCourses() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<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;
|
|
||||||
}
|
|
||||||
.tab-page {
|
.tab-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
padding-bottom: 160rpx;
|
padding-bottom: 160rpx;
|
||||||
@@ -259,4 +234,22 @@ function goMyCourses() {
|
|||||||
0% { background-position: 200% 0; }
|
0% { background-position: 200% 0; }
|
||||||
100% { background-position: -200% 0; }
|
100% { background-position: -200% 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 滚动容器 */
|
||||||
|
.scroll-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 固定 TabBar */
|
||||||
|
.tabbar-fixed {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
<template>
|
<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" />
|
<scroll-view scroll-y class="scroll-container">
|
||||||
<image src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/wave_bottom.png" mode="widthFix" class="wave-bg wave-bottom" />
|
|
||||||
</view> -->
|
|
||||||
<view class="tab-page">
|
<view class="tab-page">
|
||||||
<view class="tab-page__header">
|
<view class="tab-page__header">
|
||||||
<text class="tab-page__title">发现</text>
|
<text class="tab-page__title">发现</text>
|
||||||
@@ -28,7 +26,12 @@
|
|||||||
|
|
||||||
<view class="bottom-placeholder"></view>
|
<view class="bottom-placeholder"></view>
|
||||||
</view>
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- 固定 TabBar -->
|
||||||
|
<view class="tabbar-fixed">
|
||||||
<TabBar :active="3" />
|
<TabBar :active="3" />
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -50,33 +53,6 @@ function goPointsMall() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<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;
|
|
||||||
}
|
|
||||||
.tab-page {
|
.tab-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
padding-bottom: 160rpx;
|
padding-bottom: 160rpx;
|
||||||
@@ -139,4 +115,22 @@ function goPointsMall() {
|
|||||||
.bottom-placeholder {
|
.bottom-placeholder {
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 滚动容器 */
|
||||||
|
.scroll-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 固定 TabBar */
|
||||||
|
.tabbar-fixed {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
<template>
|
<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>
|
<view class="hand" :style="{height : handHeight + 'rpx'}" v-show="isShow"></view>
|
||||||
|
|
||||||
@@ -61,24 +56,11 @@ const handleScroll = (e) => {
|
|||||||
const distance = e.detail.scrollTop
|
const distance = e.detail.scrollTop
|
||||||
scrollDistance.value = distance
|
scrollDistance.value = distance
|
||||||
|
|
||||||
// 获取滚动容器的高度(可视区域高度)
|
console.log(`滚动距离: ${distance}`)
|
||||||
const scrollViewHeight = e.detail.scrollHeight
|
|
||||||
scrollContentHeight.value = scrollViewHeight
|
|
||||||
|
|
||||||
// 计算滚动百分比
|
// 当滚动超过一定距离时显示白色块(200px = 400rpx)
|
||||||
// 滚动百分比 = 当前滚动距离 / (内容总高度 - 可视区域高度) * 100
|
const SHOW_THRESHOLD = 50 // 滚动超过200px时显示白条
|
||||||
const maxScrollDistance = scrollContentHeight.value - windowHeight.value
|
isShow.value = distance > SHOW_THRESHOLD
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下拉刷新处理
|
// 下拉刷新处理
|
||||||
@@ -118,16 +100,27 @@ onMounted(() => {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
}, 1500)
|
}, 1500)
|
||||||
|
|
||||||
// 获取胶囊按钮高度
|
// 获取系统信息
|
||||||
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
|
||||||
const navTotalHeight = menuButtonInfo.top + menuButtonInfo.height
|
|
||||||
handHeight.value = navTotalHeight * 2.5
|
|
||||||
|
|
||||||
// 获取可视窗口高度
|
|
||||||
uni.getSystemInfo({
|
uni.getSystemInfo({
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
windowHeight.value = res.windowHeight
|
windowHeight.value = res.windowHeight
|
||||||
console.log('可视窗口高度:', windowHeight.value)
|
console.log('可视窗口高度:', windowHeight.value)
|
||||||
|
console.log('平台:', res.platform)
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 微信小程序使用胶囊按钮高度(保持原有逻辑)
|
||||||
|
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
||||||
|
const navTotalHeight = menuButtonInfo.top + menuButtonInfo.height
|
||||||
|
handHeight.value = navTotalHeight * 2.5
|
||||||
|
console.log('微信小程序胶囊按钮高度:', handHeight.value)
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
// H5和安卓App只显示状态栏高度
|
||||||
|
const statusBarHeight = res.statusBarHeight || 0
|
||||||
|
handHeight.value = statusBarHeight * 2 // 转换为rpx(1px = 2rpx)
|
||||||
|
console.log('非微信小程序状态栏高度:', handHeight.value, 'rpx')
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -145,35 +138,6 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<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 {
|
.scroll-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="scroll-container theme-light">
|
<!-- 滚动内容区域 -->
|
||||||
|
<scroll-view scroll-y class="scroll-container theme-light">
|
||||||
<view class="member-page">
|
<view class="member-page">
|
||||||
<MemberInfoHeader
|
<MemberInfoHeader
|
||||||
:user-info="userInfo"
|
:user-info="userInfo"
|
||||||
@@ -44,7 +45,10 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- TabBar -->
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- 固定 TabBar -->
|
||||||
|
<view class="tabbar-fixed">
|
||||||
<TabBar />
|
<TabBar />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -238,4 +242,14 @@ export default {
|
|||||||
@import '@/common/style/memberInfo/member-info-referral.css';
|
@import '@/common/style/memberInfo/member-info-referral.css';
|
||||||
@import '@/common/style/memberInfo/member-info-settings.css';
|
@import '@/common/style/memberInfo/member-info-settings.css';
|
||||||
@import '@/common/style/memberInfo/member-info-logout.css';
|
@import '@/common/style/memberInfo/member-info-logout.css';
|
||||||
|
|
||||||
|
/* 固定 TabBar */
|
||||||
|
.tabbar-fixed {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<template>
|
<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" />
|
<scroll-view scroll-y class="scroll-container">
|
||||||
<image src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/wave_bottom.png" mode="widthFix" class="wave-bg wave-bottom" />
|
|
||||||
</view> -->
|
|
||||||
<view class="tab-page">
|
<view class="tab-page">
|
||||||
<view class="tab-page__header">
|
<view class="tab-page__header">
|
||||||
<text class="tab-page__title">训练</text>
|
<text class="tab-page__title">训练</text>
|
||||||
@@ -30,7 +28,12 @@
|
|||||||
|
|
||||||
<view class="bottom-placeholder"></view>
|
<view class="bottom-placeholder"></view>
|
||||||
</view>
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- 固定 TabBar -->
|
||||||
|
<view class="tabbar-fixed">
|
||||||
<TabBar :active="2" />
|
<TabBar :active="2" />
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -55,33 +58,6 @@ function goCheckIn() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.bg-wrapper {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 2;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
.tab-page {
|
.tab-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
padding-bottom: 160rpx;
|
padding-bottom: 160rpx;
|
||||||
@@ -144,4 +120,22 @@ function goCheckIn() {
|
|||||||
.bottom-placeholder {
|
.bottom-placeholder {
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 滚动容器 */
|
||||||
|
.scroll-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 固定 TabBar */
|
||||||
|
.tabbar-fixed {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user