Files
jiapuapp/components/PageHeader.vue
T

283 lines
5.8 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="page-header-slot" :class="{ 'page-header-slot--root': root }">
<view class="page-header" :class="{ 'page-header--root': root }">
<!-- 根页头部使用不透明朱砂底图与透明祠堂线稿两层完整资产 -->
<image
v-if="root"
class="header-texture"
src="/static/assets/foundation/opaque/root-header-cinnabar.jpg"
mode="scaleToFill"
/>
<image
v-if="root"
class="header-hall"
src="/static/assets/foundation/transparent/root-header-hall.png"
mode="aspectFit"
/>
<view class="header-side header-side--left">
<button
v-if="root"
class="header-icon-button"
aria-label="返回首页"
@click="$emit('brand')"
>
<image
class="header-logo"
src="/static/assets/foundation/transparent/brand-seal.png"
mode="aspectFit"
/>
</button>
<button
v-else
class="header-back"
aria-label="返回上一页"
hover-class="header-back--pressed"
@click="goBack"
>
<image
class="header-back__icon"
src="/static/assets/foundation/transparent/chevron-right.png"
mode="aspectFit"
/>
</button>
</view>
<text class="header-title">{{ title }}</text>
<view class="header-side header-side--right">
<button
v-if="root"
class="header-icon-button header-notice"
aria-label="打开消息中心"
@click="$emit('notice')"
>
<image
class="header-notice-icon"
src="/static/assets/foundation/transparent/notice.png"
mode="aspectFit"
/>
<view v-if="unreadCount > 0" class="notice-dot"></view>
</button>
<button v-else class="header-action" :disabled="!action" @click="$emit('action')">{{
action
}}</button>
</view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
title: { type: String, required: true },
action: { type: String, default: "" },
root: { type: Boolean, default: false },
unreadCount: { type: Number, default: 0 },
fallbackUrl: { type: String, default: "/pages/genealogy/g01-my-genealogies" },
customBack: { type: Boolean, default: false },
});
const emit = defineEmits(["brand", "notice", "action", "back"]);
const goBack = () => {
if (props.customBack) {
emit("back");
return;
}
const stack = getCurrentPages();
if (stack.length > 1) {
uni.navigateBack();
return;
}
uni.reLaunch({ url: props.fallbackUrl });
};
</script>
<style scoped lang="scss">
.page-header-slot {
height: calc(104rpx + var(--status-bar-height, 0px));
flex: none;
}
.page-header-slot--root {
height: calc(124rpx + var(--status-bar-height, 0px));
}
.page-header {
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: 30;
display: flex;
align-items: center;
height: calc(104rpx + var(--status-bar-height, 0px));
padding: 0 24rpx;
padding-top: var(--status-bar-height, 0px);
box-sizing: border-box;
background: $brand-red;
color: #fff9ed;
transform: translateZ(0);
}
.page-header--root {
height: calc(124rpx + var(--status-bar-height, 0px));
padding-top: var(--status-bar-height, 0px);
background-color: #b52e22;
overflow: hidden;
}
.header-texture {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.header-hall {
position: absolute;
bottom: -2rpx;
left: -48rpx;
z-index: 1;
width: 476rpx;
height: 166rpx;
opacity: 0.29;
pointer-events: none;
}
.page-header--root .header-side,
.page-header--root .header-title {
z-index: 2;
}
.header-side {
display: flex;
width: 120rpx;
min-height: 88rpx;
align-items: center;
}
.header-side--left {
justify-content: flex-start;
}
.header-side--right {
justify-content: flex-end;
}
.header-icon-button {
display: grid;
width: 88rpx;
height: 88rpx;
place-items: center;
margin: 0;
padding: 0;
border: 0;
background: transparent;
line-height: normal;
}
.header-icon-button::after,
.header-back::after,
.header-action::after {
border: 0;
}
.header-logo {
width: 66rpx;
height: 66rpx;
}
.header-notice-icon {
width: 48rpx;
height: 48rpx;
}
.header-logo,
.header-notice-icon,
.notice-dot {
grid-area: 1 / 1;
}
.notice-dot {
align-self: start;
justify-self: end;
width: 14rpx;
height: 14rpx;
margin-top: 15rpx;
margin-right: 13rpx;
border: 2rpx solid $brand-red;
border-radius: 50%;
background: #fff9ed;
}
.header-action {
width: 100%;
margin: 0;
padding: 0;
border: 0;
background: transparent;
font-size: 27rpx;
line-height: normal;
}
.header-back {
display: flex;
width: 88rpx;
height: 88rpx;
align-items: center;
justify-content: flex-start;
margin: 0;
padding: 0;
border: 0;
background: transparent;
line-height: normal;
}
.header-back__icon {
width: 42rpx;
height: 42rpx;
filter: brightness(0) invert(1);
transform: scaleX(-1);
}
.header-back--pressed {
opacity: 0.62;
}
.header-action {
color: #ffe3a7;
text-align: right;
}
.header-title {
flex: 1;
overflow: hidden;
color: #fff9ed;
font-family: serif;
font-size: 35rpx;
font-weight: 700;
letter-spacing: 4rpx;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
}
.page-header--root .header-title {
color: #ffe3a7;
font-family: "STKaiti", "KaiTi", serif;
font-size: 48rpx;
letter-spacing: 5rpx;
transform: translateY(2rpx);
}
.page-header--root .header-logo {
width: 80rpx;
height: 80rpx;
transform: translate(-6rpx, -6rpx);
}
.page-header--root .header-notice {
transform: translateY(4rpx);
}
</style>