Files
gym-manage/gym-manage-uniapp/components/index/PageHeader.vue
T

144 lines
2.9 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>
<!-- 状态栏占位区 App 端生效H5/小程序无状态栏概念 -->
<view class="tab-page__status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
<!-- 导航栏主体 -->
<view class="tab-page__header">
<view v-if="showBack" :class="['tab-page__back-btn', { 'tab-page__back-btn--animate': isAnimating }]" @tap="goBack">
<text class="tab-page__back-icon"></text>
</view>
<view class="tab-page__title-wrap">
<text class="tab-page__title">{{ title }}</text>
<text v-if="subtitle" class="tab-page__subtitle">{{ subtitle }}</text>
</view>
<view v-if="$slots.right" class="tab-page__right">
<slot name="right"></slot>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
const props = defineProps({
title: {
type: String,
default: '课程'
},
subtitle: {
type: String,
default: '精品团课 · 私教 · 线上课'
},
showBack: {
type: Boolean,
default: false
}
})
const isAnimating = ref(false)
const statusBarHeight = ref(0)
onMounted(() => {
// #ifdef APP-PLUS
// App 端获取真实状态栏高度(px)
const sysInfo = uni.getSystemInfoSync()
statusBarHeight.value = sysInfo.statusBarHeight || 0
// #endif
// #ifndef APP-PLUS
// H5/小程序:状态栏由浏览器或框架处理,不额外占位
statusBarHeight.value = 0
// #endif
if (props.showBack) {
isAnimating.value = true
}
})
function goBack() {
uni.navigateBack({
fail: () => {
uni.switchTab({
url: '/pages/index/index'
})
}
})
}
</script>
<style lang="scss" scoped>
/* 状态栏占位:仅在 App 端有高度,H5/小程序为 0,背景继承页面 */
.tab-page__status-bar {
width: 100%;
}
.tab-page__header {
padding: 0 32rpx 24rpx 32rpx;
display: flex;
align-items: center;
height: 88rpx;
position: relative;
}
.tab-page__back-btn {
width: 48rpx;
height: 64rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
background: rgba(0, 0, 0, 0.06);
border-radius: 16rpx;
opacity: 0;
transform: translateX(120rpx);
transition: none;
z-index: 1;
}
.tab-page__back-btn--animate {
animation: slideInFromRight 0.4s ease-out forwards;
}
@keyframes slideInFromRight {
0% {
opacity: 0;
transform: translateX(120rpx);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
.tab-page__back-icon {
font-size: 36rpx;
color: $text-dark;
font-weight: bold;
line-height: 28rpx;
}
.tab-page__title-wrap {
flex: 1;
position: relative;
z-index: 2;
}
.tab-page__title {
display: block;
font-size: 40rpx;
font-weight: $font-weight-bold;
color: $text-dark;
}
.tab-page__subtitle {
display: block;
margin-top: 8rpx;
font-size: 24rpx;
color: $text-muted;
}
.tab-page__right {
margin-left: 16rpx;
flex-shrink: 0;
display: flex;
align-items: center;
}
</style>