Files
Docker/uniapp/youjiala/src/components/page-navbar/page-navbar.vue
T
2026-10-16 11:57:29 +08:00

176 lines
5.7 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.
<script setup lang="ts">
/**
* 文件页顶部导航栏:「返回箭头 + 左对齐标题 …… 传输入口 + 右侧两个显隐开关」。
* 根目录不显示返回(showBack=false);标题左对齐、操作图标右对齐,稳定的两端对齐结构
* (避免居中标题与右侧图标在图标增减时产生的不对称视觉负担)。
* 右侧 search/grid 两个图标分别切换页面里搜索框与快捷入口区的显隐,
* 点亮(蓝)= 对应区域显示,置灰 = 隐藏;排序按钮在 file-tab-filter 工具区。
* 传输图标是跳转入口(带进行中计数角标),不参与显隐切换;字形用自绘 SVG(transferGlyph)。
* 纯展示组件:不自己做导航与显隐逻辑,按钮语义一律 emit 给页面决定。
* 顶栏配色跟随截图(白底黑字),不并入 app-page 的绿色 u-navbar,故页面用 hide-nav 让位。
*/
import { computed } from "vue";
import { TRANSFER_ACTIVE_COLOR, transferGlyph } from "@/utils/transferGlyph";
const props = defineProps({
/** 页面标题(页面用 t() 翻译好后传进来) */
title: {
type: String,
required: true,
},
/** 是否显示返回箭头:仅进入子目录后显示 */
showBack: {
type: Boolean,
default: false,
},
/** 搜索框当前是否可见(决定开关图标高亮态) */
searchOn: {
type: Boolean,
default: true,
},
/** 快捷入口区当前是否可见(决定开关图标高亮态) */
quickOn: {
type: Boolean,
default: true,
},
/** 进行中上传任务数:>0 时传输图标点亮并挂数字角标 */
transferring: {
type: Number,
default: 0,
},
/** 传输列表入口开关:回收站等无上传场景的页面传 false */
showTransfer: {
type: Boolean,
default: true,
},
/** 快捷入口区开关:无快捷入口的页面传 false(连带隐藏切换按钮) */
showQuickToggle: {
type: Boolean,
default: true,
},
/** 搜索图标开关:无搜索场景的页面/层级传 false(如共享大厅顶层群组卡列表) */
showSearchToggle: {
type: Boolean,
default: true,
},
});
const emit = defineEmits<{
(e: "back"): void;
(e: "toggle-search"): void;
(e: "toggle-quick"): void;
(e: "transfer"): void;
}>();
/** 传输字形:有进行中任务点亮(iconfont 主色蓝),空闲置灰 */
const transferIcon = computed(() => transferGlyph(props.transferring ? TRANSFER_ACTIVE_COLOR : "#8f959e"));
</script>
<template>
<view class="page-navbar">
<view v-if="props.showBack" class="page-navbar__back" @tap="emit('back')">
<u-icon name="arrow-left" size="42" color="#1f2329" />
</view>
<text class="page-navbar__title">
{{ props.title }}
</text>
<view class="page-navbar__side page-navbar__side--right">
<!-- 传输列表入口(常显):有进行中任务时点亮 + 数字角标;回收站页隐藏 -->
<view v-if="props.showTransfer" class="page-navbar__btn page-navbar__btn--transfer" @tap="emit('transfer')">
<image class="page-navbar__transfer-img" :src="transferIcon" mode="aspectFit" />
<text v-if="props.transferring" class="page-navbar__badge">
{{ props.transferring > 99 ? "99+" : props.transferring }}
</text>
</view>
<!-- 切换搜索框显隐;无搜索场景的层级隐藏 -->
<view v-if="props.showSearchToggle" class="page-navbar__btn" @tap="emit('toggle-search')">
<u-icon name="search" size="38" :color="props.searchOn ? '#2b8fff' : '#8f959e'" />
</view>
<!-- 切换快捷入口区显隐;无快捷入口的页面隐藏 -->
<view v-if="props.showQuickToggle" class="page-navbar__btn" @tap="emit('toggle-quick')">
<u-icon name="grid" size="38" :color="props.quickOn ? '#2b8fff' : '#8f959e'" />
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.page-navbar {
position: sticky;
top: 0;
z-index: 9;
display: flex;
align-items: center;
padding: 16rpx 24rpx;
/* 透明顶栏:透出页面的浅蓝→白渐变底 */
background-color: transparent;
}
/* 右侧操作图标组:宽度自适应内容、不参与标题伸缩,标题始终左对齐 */
.page-navbar__side {
display: flex;
align-items: center;
gap: 6rpx;
min-height: 64rpx;
flex-shrink: 0;
}
.page-navbar__side--right {
justify-content: flex-end;
}
.page-navbar__back {
display: flex;
align-items: center;
justify-content: center;
width: 64rpx;
height: 64rpx;
}
/* 显隐开关按钮:与 file-tab-filter 工具图标同尺寸,保持一行工具观感 */
.page-navbar__btn {
display: flex;
align-items: center;
justify-content: center;
width: 60rpx;
height: 60rpx;
}
/* 传输入口:右上角挂进行中计数角标 */
.page-navbar__btn--transfer {
position: relative;
}
/* 自绘 SVG 传输字形:与同行 u-icon size=38 视觉对齐 */
.page-navbar__transfer-img {
width: 40rpx;
height: 40rpx;
}
.page-navbar__badge {
position: absolute;
top: 2rpx;
right: 0;
min-width: 26rpx;
padding: 0 6rpx;
border-radius: 999rpx;
font-size: 18rpx;
line-height: 26rpx;
text-align: center;
color: #ffffff;
background-color: #f0413e;
}
.page-navbar__title {
flex: 1;
min-width: 0;
text-align: left;
font-size: 38rpx;
font-weight: 600;
color: #1f2329;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>