在我眼里自定义导航分2类: 原生基础上 || 非原生基础上
总结:项目当中能原生就原生,提高性能区别
uni-app 自带原生导航栏,在pages.json里配置。
原生导航的体验更好,渲染新页面时,原生导航栏的渲染无需等待新页面dom加载,可以在新页面进入动画开始时就渲染。
原生导航还可以避免滚动条通顶,并方便的控制原生下拉刷新。
通过pages.json的配置,可以简单的、跨端的、高性能的开发业务。
但原生导航栏的扩展能力有限的。尤其是微信下,没有提供太多导航栏的配置。
在App下,pages.json里每个页面的app-plus下可以设置titleNView等更多参数,可以得到比微信小程序更丰富的扩展性。
另外,开发者也可以在必要时取消原生导航栏,使用view自行绘制导航栏。
原生基础上
- 通过app-plus属性对自定义导航扩展
https://uniapp.dcloud.io/collocation/pages?id=app-plus
文档描述:
1.原生导航能解决业务需求的情况下,尽量使用原生导航,甚至有时需要牺牲一些不是很重要的需求。
2.在App和H5下,uni-app提供了灵活的处理方案:`titleNView、subNVue`、或整页使用nvue。
3.但在小程序下,因为其自身的限制,没有太好的方案。有必要的话,也可以用条件编译分端处理。
所以主要是使用app-plus的titleNView(导航栏)、subNVue(子窗口)属性
- titleNView(导航栏) 以下都是在titleNView属性下操作
https://uniapp.dcloud.io/collocation/pages?id=app-titlenview
常用的是按钮属性:https://uniapp.dcloud.io/collocation/pages?id=app-titlenview-buttons
titleNView.buttons.type
除了type文档还有其它属性
"buttons": [{"type": "menu"},{"type": "favorite"}]
其它类型
"forward":前进按钮 "back":后退按钮
"share":分享按钮 "favorite":收藏按钮
"home":主页按钮 "menu":菜单按钮
"close":关闭按钮 "none":无样式,不显示图标
自定义返回按钮
titleNView.backButton
用法跟button一样,但需需要在autoBackButton设置为true时生效
https://uniapp.dcloud.io/collocation/pages?id=app-titlenview-backbuttonstyles
titleNView.<其它属性>
https://uniapp.dcloud.io/collocation/pages?id=app-titlenview
出了按钮跟返回按钮 还有其它属性比如
searchInput 原生导航栏上的搜索框配置
homeButton 标题栏控件是否显示Home按钮
backgroundImage 背景图片路径 等等
这些按钮的生命周期
//其中事件参数e.index值为点击按钮在buttons数组的索引值,从0开始
onNavigationBarButtonTap(e) 该生命周期监听按钮的点击事件
//设有搜索框时搜索框的生命周期
onNavigationBarSearchInputChanged()//搜索框内容变化
onNavigationBarSearchInputConfirmed()//搜索事件也是手机的回车事件
更改这些按钮的方法
webView对象文档及其它方法https://www.html5plus.org/doc/zh_cn/webview.html#
搜索WebviewObject关键字第47个处
// #ifdef APP-PLUS
var webView = this.$mp.page.$getAppWebview(); //必须先获取webview对象
webview.showTitleNViewButtonRedDot()//调用方法显示红点
webview.showTitleNViewButtonRedDot()//调用方法隐藏红点
webview.setTitleNViewButtonBadge()//修改红点角标
webview.setTitleNViewButtonStyle()//修改按钮
// #endif
这些是原生基础上app-plus的titleNView(导航栏),还有个subNVue(子窗口)属性
- subNVue(子窗口)属性 以下都是在subNVue(子窗口)属性下操作
配置
subNVue.style
https://uniapp.dcloud.io/collocation/pages?id=app-subnvuesstyle
subNVue是 vue 页面的子窗体,它不是全屏页面,就是用于解决 vue 页面中的层级覆盖和原生界面自定义用的。它也不是组件,就是一个原生子窗体
nvue快速上手
https://uniapp.dcloud.io/nvue-outline?id=_1%e6%96%b0%e5%bb%banvue%e9%a1%b5%e9%9d%a2
方法
const subNVue = uni.getSubNVueById('原生子窗体的 ID');获取子窗口对象
用于开发弹窗与导航
subNVue对象的方法
https://uniapp.dcloud.io/api/window/subNVues?id=app-getsubnvuebyid
nvue 跟 vue 的通讯
https://ask.dcloud.net.cn/article/36010
非原生基础上
全局取消原生导航栏"navigationStyle":"custom"
- 1.取消原生导航栏
"navigationStyle":"custom"
带来的问题:有些新组件已经解决了这个问题. 状态栏(显示电量的那一栏,不是导航栏),导航栏直接陷进去了.
- 2.处理状态栏问题
App因为默认为沉浸式,去除导航栏后,页面顶部会直通到状态栏的区域
uni-app 提供内置 CSS 变量解决
https://uniapp.dcloud.io/frame?id=css变量
写成代码后直接解决了我这个问题
<!-- #ifdef APP-PLUS -->
<view class="status_bar">
<view class="top_view"></view>
</view>
<!-- #endif -->
/*
* !!!然后在这下面放自己的导航组件就行
* https://ext.dcloud.net.cn/plugin?id=52(这个我感觉就可以了)
*/
//css部分
.status_bar {
height: var(--status-bar-height);
width: 100%;
background-color: #F8F8F8;
}
.top_view {
height: var(--status-bar-height);
width: 100%;
position: fixed;
background-color: #F8F8F8;
top: 0;
z-index: 999;
}
- 3.H5、小程序、App端状态栏都不一样,需要重新计算处理,下面是别人处理好的代码
直接使用,在App.vue里面设置即可
onLaunch: function() {
uni.getSystemInfo({
success:function(e){
Vue.prototype.statusBar = e.statusBarHeight
// #ifndef MP
if(e.platform == 'android') {
Vue.prototype.customBar = e.statusBarHeight + 50
}else {
Vue.prototype.customBar = e.statusBarHeight + 45
}
// #endif
// #ifdef MP-WEIXIN
let custom = wx.getMenuButtonBoundingClientRect()
Vue.prototype.customBar = custom.bottom + custom.top - e.statusBarHeight
// #endif
// #ifdef MP-ALIPAY
Vue.prototype.customBar = e.statusBarHeight + e.titleBarHeight
// #endif
}
})
},
禁用原生导航后 还是可以通过接口改变样式的
https://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.setStatusBarStyle
页面禁用原生导航栏后,仍可设置页面的 navigationBarTextStyle 属性
注意部分低端Android手机(4.4)自身不支持设置状态栏前景色。