
本节主要讲头部 + 页面布局,讲解添加头部标题栏基础功能。
# 头部 + 页面布局
从实战开发开始的两个页面都没有添加头部标题栏,只是把标题栏进行了取消。在项目的根目录下的 pages.json 文件,设置 app-plus 的 titleNView 为 false 即可;
/* pages.json */
{
"path": "pages/mine/index",
"style": {
"navigationBarTitleText": "我的",
"app-plus":{
"titleNView": false
}
}
},
视频页实际头部效果:

这个页面的标题栏开发会相对容易一些,因此拿到这里来讲开发导航栏。
由于 h5 是运行在浏览器中的,我们并不能对标题栏进行样式设置,故在差异化下,H5 没有应用头部。但是在 app 我们是可以设置标题栏的,新版的小程序也开始支持标题栏的设置。我们的 Uniapp 项目并不是操作原生 app 组件,因此标题栏的设置可以说是 webview 的一个样式模拟。取消标题栏的是以手机状态栏(电池栏)开始自上而下排版的,这一块我们也要隔开。
看到开头的大图,图片上画的两个很明显的边框分为两块,头部与内容区。要想更接近 app 的原生效果,就要看页面的组成。我们在写页面的时候可以把导航栏固定,然后内容区用 scroll-view 组件撑开整个页面:
<view>
<view class="navbar">
<!-- 这里是标题栏 -->
</view>
<scroll-view scroll-y="true" class="page-content">
这里是内容区
</scroll-view>
</view>
.navbar{
position: fixed;
top:0;
width:100%;
height:44px;
}
.page-content {
position: fixed;
top: 44px; // 距离标题栏高度
left: 0;
right: 0;
bottom: 0px;
}
这样就可以实现基本的页面布局,内容区铺满整个页面(除标题栏外和底部导航)。
在这里我们可以使用 Uniapp 官方的扩展组件 NavBar 导航栏。可以友好的处理左右边的事件,甚至可以以插槽的方式自定义功能复杂的标题栏。因此可以改造代码:
<view>
<!-- #ifdef APP-PLUS || MP-WEIXIN -->
<uni-nav-bar fixed :status-bar="true" title="我的音乐" @clickLeft="goCloud" @clickRight="goCloud">
<block slot="left"><image class="top-img left" src="/static/image/mine/l.png"></image></block>
<!-- #ifdef APP-PLUS -->
<block slot="right"><image class="top-img" src="/static/image/mine/r.png"></image></block>
<!-- #endif -->
</uni-nav-bar>
<!-- #endif -->
<!-- #ifdef APP-PLUS || MP-WEIXIN -->
<scroll-view scroll-y="true" class="page-content">
<!-- #endif -->
这里是内容区
<!-- #ifdef APP-PLUS || MP-WEIXIN -->
</scroll-view>
<!-- #endif -->
</view>
固定导航栏在 uni-nav-bar 组件中添加 fixed,添加 :status-bar="true" 适配状态栏的高度下渲染,并添加左右触发事件回调。由于这一块仅在 app 中需要设置标题栏,因此代码进行了条件编译 <!-- #ifdef APP-PLUS -->。
添加完头部标题栏的 APP 页面效果图:

添加完头部标题栏的微信小程序页面效果图:

小程序的载体是运营方 app,会有运营方的设计差异在。因此在设计整个项目之初,哪些功能是否适用的,是否可以在这个端使用的,都要做出评估。功能设计上也要有所取舍。如果产品经理设计一个功能需要在 H5 中调用用户的通讯录,就算程序员再优秀或者框架再实用,H5 也是做不到的调用通讯录的。开发之前要考虑他们所提供的 API 和性能能否满足产品需求。
# App、小程序与 H5 的能力对比
- App 能够承载更多产品功能,一些复杂的功能能够通过原生实现;
- 小程序可承载产品核心功能,较复杂的功能难以实现,优点是用完就走,缺点是需要在某个平台的 app 下打开,数据难以共享;
- H5能够脱离生态下运行,打开即可。一个网站多终端匹配。但是数据难以持久化,网页关闭后需要重新加载。根据手机的性能用户体验各有差别,流畅度不够高。
就比如这款 Uniapp Music 应用,我做一些取舍小改动,顶部右侧的功能图标不在小程序显示:
<!-- #ifdef APP-PLUS -->
<!-- 条件编译后只在 app 显示 -->
<block slot="right"><image class="top-img" src="/static/image/mine/r.png"></image></block>
<!-- #endif -->

通过这个头部的组件应用介绍,整个应用都可以改造成自定义的标题栏,在这里组件与插槽 slot 的优点就显露出来了。复用的同时又可以实现功能的自定义。下面我们看一下 slot 插槽的使用。
# slot 插槽的使用场景
父组件向子组件传递 dom 时会用到插槽。插槽,也就是 slot,是组件的一块模板,这块模板显示不显示、以及怎样显示由父组件来决定。比如头部代码的具名插槽:
<uni-nav-bar fixed :status-bar="true" title="我的音乐" @clickLeft="goCloud" @clickRight="goCloud">
<block slot="left"><image class="top-img left" src="/static/image/mine/l.png"></image></block>
<block slot="right"><image class="top-img" src="/static/image/mine/r.png"></image></block>
</uni-nav-bar>
<!-- uni-nav-bar.vue 组成 -->
<view class="uni-navbar">
<slot name="left" /> <!-- 我会被替换成 <image class="top-img left" src="/static/image/mine/l.png"></image> -->
<view>标题</view>
<slot name="right" />
</view>
slot="left",slot="right",这两个指定了名字,因此叫具名插槽,会在子组件指定的位置渲染。比如 slot="left" 的这个元素会在组件 uni-nav-bar 中 <slot name="left" /> 显示,相当于替换掉了。插槽显示的位置由子组件自身决定,slot 在子组件中的位置,决定了父组件传过来的显示模板的位置。
# 导航栏 scroll-view
页面的整个内容区由 scroll-view 组件包裹,当前页面的导航栏也是由 scroll-view 组件组成,内容区主要负责用户上下浏览设置 scroll-y,而导航栏负责左右浏览设置 scroll-x。
# 小结
- 注重整页的布局,尽可能的还原 app 浏览模式;
- 标题栏可以使用官方的扩展组件 uni-nav-bar;
- 插槽 slot 的使用可以在父级中自定义组件的功能,指定名称可以决定显示模板的位置;
- 开发应用之前要考虑不同 app 、小程序、H5所提供的 API 和性能能否满足产品需求,这是开发设计的首要考虑的地方。
- 本章代码 uni-course-实战开发我的页 (opens new window)。