uni-app:通过mod-nav-bar了解css的基本样式


<!-- 逻辑与数据定义区:用于定义组件的 响应式数据、方法、生命周期、引入依赖 等逻辑 -->
<!-- <script setup> 是 Vue 3 引入的一种编译时语法糖,用于更简洁地编写组合式 API(Composition API)。 -->
<!-- 使用 <script setup> 语法糖后,你就不需要手动写 setup() 函数,
也不用写 export default {},更不用 return 数据 ——
Vue 编译器会自动帮你处理。 -->
<!-- setup 是 Vue 3 组件中用于定义响应式状态、方法、计算属性、监听器和生命周期钩子的“逻辑入口函数”。 -->
<script setup>
	
</script>

<!-- 视图结构(UI 模板):定义页面的 HTML 结构(在 uni-app 中是跨平台的标签)。 -->
<!-- <template> 是 Vue 的根模板容器,只能有一个根元素(这里就是 <view>)。 -->
<template>
	<!-- uni-app 使用 <view> 而不是 <div>,因为:
	<view> 是 uni-app 提供的跨平台组件,
	在 H5 上编译为 div,在微信小程序上编译为 view,
	在 App 上使用原生 View。 -->
	<!-- 这里的 class 的值(如 "mod-nav-bar"、"fixed-wrap"、"status-bar" 等)
	都是开发者自己定义的类名,
	它们的作用就是 在 <style> 中通过 CSS 选择器来绑定样式。 -->
	<!-- 这是一个 自定义导航栏(Custom Navigation Bar) 的典型结构,用于替代 uni-app 默认的原生导航栏。 -->
	<!-- 最外层:.mod-nav-bar:整个自定义导航栏的容器。 -->
	<view class="mod-nav-bar"> 
	<!-- .fixed-wrap —— 真正固定在顶部的部分 -->
		<view class="fixed-wrap">
			<!-- .status-bar:占位 状态栏(Status Bar) 的高度(如 iPhone 的刘海区、安卓的时间/信号区)。 -->
			<!-- 为什么需要?不同手机状态栏高度不同(iPhone 14 是 44px,安卓可能是 25px)。
			uni-app 提供了 API 获取这个高度: const statusBarHeight = uni.getSystemInfoSync().statusBarHeight-->
			<view class="status-bar"></view>
			<!-- .title-bar 作用:模拟原生导航栏的“标题区域”(通常是 44px 或 88rpx 高)。 -->
			<view class="title-bar">
				<!-- 左侧区域:返回箭头 <、关闭图标、侧边栏按钮等 -->
				<view class="arrow-wrap">
					<!-- 这个 icon 来自 https://uniapp.dcloud.net.cn/component/uniui/uni-icons.html -->
					<!-- 在这个项目的: .../uni_modules/uni-icons -->
					<uni-icons class="icon" type="left" size="30"></uni-icons>
				</view>
				<!-- 中间区域:页面标题文字、Logo、搜索框等 -->
				<view class="text-wrap">
					标题
				</view>
				<!-- 右侧区域:分享、更多(⋯)、消息图标、发布按钮等 -->
				<view class="menu-wrap"></view>
			</view>
		</view>
		<!-- .block-wrap —— 占位块(关键!) -->
		<!-- 在页面正常流中插入一个空白块,高度 = 状态栏 + 标题栏。 -->
		<!-- 为什么需要?因为 .fixed-wrap 是 position: fixed(脱离文档流),
		如果不加这个占位块,页面内容会从屏幕顶部开始渲染,被导航栏盖住! -->
		<!-- 所以 .block-wrap 的高度必须等于 .fixed-wrap 的总高度,把页面内容“推下去”。 -->
		<view class="block-wrap"></view>
	</view>

</template>

<!-- 样式定义区:为当前组件定义 CSS 样式。 -->
<!-- lang="scss"是 <style> 标签的一个属性,表示当前样式块使用 SCSS 语法来编写 CSS。
 默认情况下,<style> 里写的是普通 CSS。
 但如果你加上 lang="scss",就可以使用 SCSS 预处理器的高级功能,
 比如:嵌套规则、变量($primary-color)、混合(@mixin)、条件判断、循环等
 -->
 <!-- scoped 是 <style> 标签的一个属性(attribute),用于实现 CSS 样式作用域隔离。
 默认情况下,一个 .vue 文件中的 CSS 会全局生效,可能影响其他页面。
 加上 scoped 后,这些样式只作用于当前组件。
 -->
<style lang="scss" scoped>
	// 创建一个固定在顶部的自定义导航栏
	// 最外层容器:.mod-nav-bar,整个导航栏模块的根容器。
	.mod-nav-bar{
		// 设置导航栏宽度
		// uni-app 中,750rpx = 屏幕宽度(设计稿通常以 iPhone 6/7/8 的 375pt 为基准,1pt = 2rpx)。
		width: 750rpx;
		// 固定定位容器:.fixed-wrap
		.fixed-wrap{
			// position: fixed:让这个容器脱离文档流,固定在屏幕顶部(即使页面滚动也不会动)。
			position: fixed;
			// left: 0; top: 0; width: 100%:贴合屏幕左上角,横跨全屏。
			left:0;
			top:0;
			width: 100%;
			// 灰色背景
			background: #ccc;
			// 状态栏占位区:.status-bar
			.status-bar{
				// 
				width: 100%;
				// 这是一个临时写死的值(实际应动态获取)。
				height: 30rpx;
				// 红色边框,仅用于调试(方便看到这个区域的位置和高度)。
				border:1px solid red;
			}
			.title-bar{
				// display: flex:启用 Flex 弹性布局(现代布局首选)。
				// 关于弹性布局:https://www.linnote.space/2025/08/15/Flutter-05-flex/
				// 主轴(main axis):默认是 水平方向(从左到右)
				// 交叉轴(cross axis):与主轴垂直,默认是 垂直方向(从上到下)
				display: flex;
				width: 100%;
				
				//text-align 的本意是:它是用于控制块级元素内部“行内内容”(inline content)的水平对齐方式。
				//一旦你给一个容器设置了 display: flex,它的直接子元素就变成了“弹性项目(flex items)”,不再是普通的 inline 或 block 元素。
				// 此时,text-align 只会影响子元素内部的文本,而不会影响子元素本身的位置。
				// 它只会让 .arrow-wrap、.text-wrap、.menu-wrap 各自内部的文本居中(但这些子元素本身已经是块级,且内容通常只有一个字,所以看不出效果)。
				// text-align: center;
				
				// 让子元素左右对齐:第一个靠左,最后一个靠右,中间的自动居中。
				// 正好对应:左(返回图标)— 中(标题)— 右(菜单)
				// justify-content:控制主轴(水平)
				justify-content:space-between;
				// align-items:控制交叉轴(cross axis)对齐
				// align-items 控制 Flex 容器中所有子元素在「垂直方向」上的对齐方式(当主轴是水平的时候)。
				align-items: center;
				// 标题栏高度(约 50px,比原生 44px 稍高,可自定义)。
				height: 100rpx;
				// 绿色边框,仅用于调试。
				border:1px solid green;
				// 左侧区域:.arrow-wrap
				.arrow-wrap {
				    height: 100%;
				    width: 80rpx;
					// flex-shrink:控制是否允许“缩小”
					// flex-shrink: 0:禁止该元素在空间不足时被压缩(保持固定宽度)。
					// flex-shrink: 1(默认)→ 允许缩小
					/* 它的作用场景:
						当 所有子元素的总宽度 > 容器宽度 时,浏览器会尝试“压缩”某些子元素来避免溢出。
							如果某个子元素 flex-shrink: 1,它会被压缩(变窄)
							如果 flex-shrink: 0,它死守原始宽度,不参与压缩*/
				    flex-shrink: 0;
				    display: flex;
					// 让内部图标垂直居中
				    align-items: center;
				}
				// 中间区域:.text-wrap
				.text-wrap {
					/*
					flex: 是 flex-grow, flex-shrink, flex-basis 三个属性的简写形式
					关于这三个的意思,可以查看:https://www.linnote.space/2023/06/01/IntroductionOfHtmlCssJs/
					 三种写法
					flex: 1;                            最常见 
					flex: 1 1 0%;                       等价于 flex: 1
					flex: <flex-grow> <flex-shrink> <flex-basis>;
					flex: 0	== flex: 0 1 auto == 不伸不缩,保持原始尺寸(常用于固定宽度元素)
					flex: 1	== flex: 1 1 0%	== 占满剩余空间(最常用!)
					flex: auto == flex: 1 1 auto == 按内容宽度为基础,再分配剩余空间
					flex: none == flex: 0 0 auto == 完全固定尺寸(等同于 width + flex-shrink:0)
					flex: 2 == flex: 2 1 0%	== 分配空间的比例是 flex:1 的 2 倍
					
					*/
					// flex: 1:表示“占据剩余所有空间”。
					// 因为左右两侧是固定宽度,中间就会自动居中(配合父容器的 justify-content: space-between)。
					// 文字内容会自然居中(如果需要强制居中,可加 text-align: center)。
				    flex: 1;
					text-align: center; /* ✅ 这里才需要!让文字在中间区域居中 */
					/*
					.text-wrap 占据中间所有剩余空间(flex: 1)
					它内部的“首页”文字通过 text-align: center 在这个宽区域内水平居中
					左右两个区域固定宽度,整体看起来就是“左图标 - 居中标题 - 右图标”
					
					*/
				}
				// 右侧区域:.menu-wrap
				.menu-wrap {
				    height: 100%;
				    width: 80rpx;
				    flex-shrink: 0;
				}
			}
		} 
	}
</style>

×

喜欢就点赞,疼爱就打赏