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

142 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>
<!-- 状态栏占位区为刘海屏和安全区域留出空间 -->
<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(() => {
// 所有平台获取状态栏高度,为刘海屏/状态栏留出安全空间
const sysInfo = uni.getSystemInfoSync()
statusBarHeight.value = sysInfo.statusBarHeight || 0
if (props.showBack) {
isAnimating.value = true
}
})
function goBack() {
uni.navigateBack({
fail: () => {
uni.switchTab({
url: '/pages/index/index'
})
}
})
}
</script>
<style lang="scss" scoped>
/* 状态栏占位:适配所有平台,包含刘海屏安全区域 */
.tab-page__status-bar {
width: 100%;
/* iOS 刘海屏额外安全区域 */
padding-top: constant(safe-area-inset-top); /* iOS 11.0-11.2 */
padding-top: env(safe-area-inset-top); /* iOS 11.2+ */
box-sizing: content-box;
}
.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>