• uni-app导航栏开发大全及注意事项


      在开发导航栏之前,建议把官方的这篇导航栏示例看完,基本大部分功能都能满足,有代码及示例图,很好的案例:导航栏示例应用

      uni-app 自带原生导航栏,在pages.json里配置。原生导航的体验更好,渲染新页面时,原生导航栏的渲染无需等待新页面dom加载,可以在新页面进入动画开始时就渲染。原生导航还可以避免滚动条通顶,并方便的控制原生下拉刷新。通过pages.json的配置,可以简单的、跨端的、高性能的开发业务。

      但原生导航栏的扩展能力有限的。尤其是微信下,没有提供太多导航栏的配置。在App下,pages.json里每个页面的app-plus下可以设置titleNView等更多参数,可以得到比微信小程序更丰富的扩展性。

      另外,开发者也可以在必要时取消原生导航栏,使用view自行绘制导航栏。

    一、原生导航栏

    1、原生导航栏的通用配置

      原生导航栏的配置,均在pages.json里,每个page下面的style配置中的navigationBar各个参数配置,即为通用配置,小程序、app、h5均生效。参考https://uniapp.dcloud.io/collocation/pages?id=style

    2、全局取消原生导航栏

      在pages.json的globalStyle里,有个navigationStyle设置,默认是default,即带有原生导航栏。

      也可以设置为custom,在设为custom后,所有页面都没有原生导航。

      但在微信小程序里,右上角始终都有一个胶囊按钮,很多微信小游戏界面上也没原生导航栏,但有胶囊按钮。

      一般App里不会使用这个参数配置。建议个别页面单独设置不使用原生导航,具体见下。

    3、单独去除原生导航栏

      支持通过如下方法取消单独一个页面的原生导航栏。但小程序右上角胶囊按钮仍然去不掉。页面配置 navigationStyle 为 custom:

    {  
        "path" : "pages/log/log",  
        "style" : {  
            "navigationStyle":"custom"  
        }  
    }

    二、原生导航栏在App侧的扩展

      微信小程序的设计里,没有给原生导航提供太多自定义能力,在开发App时是不够用的。pages.json里,每个page下面的style下面还有一个子扩展节点:app-plus。
    这个节点定义了在5+App环境下,也即iOS、Android环境下,增强的配置。其中有一个子节点titleNView,这个是5+规范里webview页面的原生导航窗体规范。
    参考https://uniapp.dcloud.io/collocation/pages?id=app-plus

    1、App去除导航栏后改变状态栏样式

      App因为默认为沉浸式,去除导航栏后,页面顶部会直通到状态栏的区域,可能出现如下需求:

    • 改变状态栏文字颜色:设置该页面的 navigationBarTextStyle 属性,可取值为 black/white。如果想单独设置颜色,App端可使用plus.navigator.setStatusBarStyle设置。部分低端Android手机(4.4)自身不支持设置状态栏前景色。
    • 改变状态栏背景颜色:通过绘制一个占位的view固定放在状态栏位置,设置此view的背景颜色,即可达到想要的效果,uni-app提供了一个状态栏高度的css变量,具体参考:http://uniapp.dcloud.io/frame?id=css%E5%8F%98%E9%87%8F

      以下为示例:

    <!-- #ifdef APP-PLUS -->  
    <view class="status_bar">  
        <view class="top_view"></view>  
    </view>  
    <!-- #endif -->
    
    .status_bar {  
        height: var(--status-bar-height);  
         100%;  
        background-color: #F8F8F8;  
    }  
    .top_view {  
        height: var(--status-bar-height);  
         100%;  
        position: fixed;  
        background-color: #F8F8F8;  
        top: 0;  
        z-index: 999;  
    }

    2、给原生导航栏添加自定义按钮

      注意:按钮的点击事件需要在页面监听onNavigationBarButtonTap事件。页面监听代码如下:

    // 页面监听代码如下:
    export default {  
        data() {  
            return {}  
        },  
        onNavigationBarButtonTap() {  
            console.log("点击了自定义按钮");  
        }  
    }  
    
    // pages.json配置如下:
    {  
        "path": "pages/log/log",  
        "style": {  
            "navigationBarTitleText": "hello",  
            "app-plus": {  
                "titleNView": {  
                    "buttons": [{  
                        "text": "ue534",  
                        "fontSrc": "/static/uni.ttf",  
                        "fontSize": "22px"  
                    }]  
                }  
            }  
        }  
    }

      buttons的text推荐使用字体图标。如果按钮使用的汉字或英文较长,推荐把字体改小一点,或者调节按钮宽度等值。配置button的背景颜色为透明:background:'rgba(0,0,0,0)'。

    3、原生导航栏自定义按钮带红点和角标

    {  
        "path" : "nav-dot/nav-dot",  
        "style" : {  
            "navigationBarTitleText" : "导航栏带红点和角标",  
            "app-plus" : {  
                "titleNView" : {  
                    "buttons" : [  
                        {  
                            "text" : "消息",  
                            "fontSize" : "14",  
                            "redDot" : true  
                        },  
                        {  
                            "text" : "关注",  
                            "fontSize" : "14",  
                            "badgeText" : "12"  
                        }  
                    ]  
                }  
            }  
        }  
    }

    4、原生导航栏自定义按钮带下拉选择(城市选择)

    {  
        "path" : "nav-city-dropdown/nav-city-dropdown",  
        "style" : {  
            "navigationBarTitleText" : "导航栏带城市选择",  
            "app-plus" : {  
                "titleNView" : {  
                    "buttons" : [  
                        {  
                            "text" : "北京市",  
                            "fontSize" : "14",  
                            "select" : true,  
                            "width" : "auto"  
                        }  
                    ]  
                }  
            }  
        }  
    }

    5、导航栏上的原生搜索框

      原生导航栏支持放置原生搜索框,可点击直接弹出软键盘,也可以点击后跳转到新页面搜索。因代码较多,此处不列,请参考hello uni-app的模板-顶部导航标题栏示例。如需动态修改searchInput,或者获取searchInput的placehold,参考uni-app动态修改App端导航栏

    6、配置原生导航栏的透明渐变

      原生导航栏还支持透明渐变效果,页面刚载入时没有导航标题,页面内容通顶到状态栏里,页面向下滚动后标题栏渐变出现。

    {  
        "path": "pages/log/log",  
        "style": {  
            "navigationBarTitleText": "hello",  
            "app-plus": {  
                "titleNView": {  
                    "type": "transparent"  
                }  
            }  
        }  
    }

      实际上可用的titleNView设置还有很多,详细的api见http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewTitleNViewStyles

      透明渐变的导航栏的button图标有一个默认的灰色背景圈,防止背景图和按钮前景颜色相同导致按钮无法看清。如果要去掉这个灰色背景图,可以配置button的背景颜色为透明:background:'rgba(0,0,0,0)'

    7、原生导航栏绘制图片

      titleNView新版配置可以直接配图片,还支持Gif图。但这里提供一个黑科技写法,通过在titleNView里配置tags,可以实现导航栏绘制图片的效果:

    {  
        "path" : "nav-image/nav-image",  
        "style" : {  
            "app-plus" : {  
                "titleNView" : {  
                    "titleText" : "",  
                    "tags" : [  
                        {  
                            "tag" : "img",  
                            "src" : "/static/nav.png",  
                            "position" : {  
                                "left" : "auto",  
                                "top" : "auto",  
                                "width" : "110px",  
                                "height" : "26px"  
                            }  
                        }  
                    ]  
                }  
            }  
        }  
    }

      通过配置 tags 除了可以绘制图片,还可以绘制更多丰富的内容,如:richtext(富文本)、font(文本)、input(输入框)、rect(矩形区域)。详情参考:titleNViewtags。以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

    8、通过setStyle方式动态修改原生导航栏样式

      如果需要js动态修改导航栏,uni有跨端的api可修改标题、背景色、前景色。这部分是app、小程序、h5都支持的,参考https://uniapp.dcloud.io/api/ui/navigationbar

      对于app侧扩展的设置,比如自己添加的buttons,则需使用plus的js api来动态设置。在App端可以通过得到webview对象,通过setStyle方法重新设置,包括修改webview对象的titleNview属性,以达到修改标题栏按钮文字及样式的功能。具体参考:https://ask.dcloud.net.cn/article/35374

    9、App侧使用subnvue自行绘制原生导航

      nvue其实是weex上补充了uni的api。uni-app支持使用nvue页面,也就是weex原生引擎,绘制顶部的原生导航栏。

      在hello uni-app的API-界面示例中,有subnvue示例,里面顶部导航栏是渐变色的,这就是subnvue的原生导航栏。在pages.json的配置如下:

    {  
        "path": "subnvue/subnvue",  
        "style": {  
            "app-plus": {  
                "titleNView": false,  
                "subNVues": [{  
                    "id": "nav",  
                    "path": "subnvue/subnvue/nav",  
                    "type": "navigationBar"  
                }]  
            }  
        }  
    }

      从HBuilderX2.6.3起,titleNView直接支持了背景图、渐变色,不再需要通过subnvue的方式了。而且性能比subnvue更好。

    10、取消原生导航栏后,使用前端标签组件模拟绘制导航栏

      不管是全局取消原生导航栏,还是在App下某个页面取消原生导航,如果还想自己绘制一些个性化的title,往往会使用view组件。尤其是App的首页,顶部经常有各种特殊设置,此时需要自己使用前端技术来绘制导航。

      导航栏应该是由状态栏和标题栏构成,状态栏的高度为 var(--status-bar-height) 此变量为uni-app框架提供仅在在css生效,标题栏的高度设为88px,整个状态栏的高度应为: calc(var(--status-bar-height) + 88px)(upx主要针对宽度,高度无所谓还可以使用px)

    .title-contents{  
        height: calc(var(--status-bar-height) + 88px);  
    }  
    .status{  
        height: var(--status-bar-height);  
    }  
    .titles{  
        height: 88px;  
    }

      状态栏和标题栏都应固定在页面顶部,需设置 position:fixed,标题栏的top应为状态栏的高度

    .top-view{  
         100%;  
        position: fixed;  
        top: 0;  
    }  
    .titles{  
        top: var(--status-bar-height);  
    }

      绘制的返回箭头需要绑定点击事件,返回上一个页面

    <view class="titleLeftButton" @click="backButton"></view>  
    
    methods:{  
        backButton(){  
            uni.navigateBack()  
        }  
    }

      以下为导航栏组件的部分代码

    <template>  
        <view class="title-contents">  
            <view class="top-view status" :style="{background:statusColor}"></view>  
            <view class="_top titles" :style="{background:statusColor}">  
                <view class="titleLeftButton" @click="backButton" v-if="showLeftButton"></view>  
                <view class="titleText" :class="titleClass">{{titleText}}</view>  
                <view class="titleRightButton" @click="rightButton" v-if="showRightButton"></view>  
            </view>  
        </view>  
    </template>  
    <script>  
        export default {  
            props:{  
                titleText:{  
                    type:String,  
                    default:""  
                },  
                statusColor:{  
                    type:String,  
                    default:"#8F8F94"  
                },  
                showLeftButton:{  
                    type:Boolean,  
                    default:true  
                },  
                showRightButton:{  
                    type:Boolean,  
                    default:false  
                }  
            },  
            methods:{  
                backButton(){  
                    uni.navigateBack()  
                },  
                ...  
            }  
        }  
    </script>  
    <style>  
        ...  
        .top-view{  
             100%;  
            position: fixed;  
            top: 0;  
        }  
    </style>  

      若页面不需要标题栏,只需一个状态栏的view占位,那么只需在页面添加一个view即可不需要引入外部组件以免影响性能。

    <view class="status-contents">  
        <view class="status top-view"></view>  
    </view>
    
    //css  
    .status-contents{  
        height: var(--status-bar-height);  
    }  
    .top-view{  
         100%;  
        position: fixed;  
        top: 0;  
    }  
    .status{  
        height:var(--status-bar-height);  
    }

      uni ui里有前端实现的自定义导航栏组件,推荐不要自己写,直接用写好的组件,https://ext.dcloud.net.cn/plugin?id=52,hello uni-app的uni ui中也有示例。

    三、注意事项

      取消原生导航栏后,自己使用HTML自定义组件模拟导航栏,会有很多性能体验问题:

    1、加载不如原生导航快

    2、下拉刷新无法从自定义的导航栏组件下面下拉。除非使用前端做下拉刷新,但性能不如自带的原生下拉刷新。

    3、必须取消页面的bounce效果,否则滚动到顶时再拖屏幕,在iOS上发现title也被拖下来了。

    4、滚动条会通顶。所以除非不得以,不要取消原生导航栏。

      如必须使用,注意如下几点:

    (1)涉及到导航栏高度的css尽量放置在App.vue里面以提高渲染速度(css渲染顺序:先渲染App.vue里面的css,再渲染页面css)

    (2)如果是深色造成闪屏,需要在pages.json的titleNView下配置webview的背景色

    (3)状态栏颜色应设置默认颜色,若非必要,不建议修改其颜色

    (4)减少在组件中使用 :style="" 的使用以提高性能

    (5)下拉刷新使用circle方式,并设置offset,让下拉刷新的圈从指定位置开始下拉,具体见pages.json配置文档

      有个高频场景是App“首页”的title自定义,如果实现的效果很个性化,那么使用plus.nativeObj.view的方案会过于复杂,由于首页并不存在新页面进入立即渲染的压力,所以App首页如果要大幅定制,推荐使用前端view绘制,而不是使用plus.nativeObj.view。

      如果把自定义导航封装成组件,虽然多个页面引入方便,但性能下降,因为这种自定义组件的加载是晚于页面基本元素的,会导致新页面进入动画时无法渲染title。
    所以导航条这种要求在动画期渲染的东西,尽量不要使用自定义组件方式。

      在hello uni-app示例中有各种导航栏的源码:在扩展ui中有前端自定义导航栏,在模板中有各种原生的导航栏,大多数情况复制这些代码就够了。

  • 相关阅读:
    tomcat server.xml 配置示例
    Vue学习1:实例及生命周期
    flex布局
    从输入一个URL到页面完全显示发生了什么?
    webstorm配置eslint【标记错误,修复错误】
    JavaScript实现八大内部排序算法
    es6(六):module模块(export,import)
    es6(五):class关键字(extends,super,static)
    es6(四):Symbol,Set,Map
    es6(三):es6中函数的扩展(参数默认值、rest参数、箭头函数)
  • 原文地址:https://www.cnblogs.com/goloving/p/14370072.html
Copyright © 2020-2023  润新知