uni-app跨端自定义导航栏

90 阅读1分钟

一.如果只要求App和H5,不考虑微信的自适应

那么下面的这个配置就够了 ``

"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages { "path": "pages/index/index", "style": { "navigationBarTitleText": "百年奥莱", "navigationBarBackgroundColor": "#FFFFFF", "app-plus": { "titleNView": { "buttons": [{ "float": "left", "fontSrc": "./static/iconfont/iconfont.ttf", "text": "\ue637" }, { "float": "right", "fontSrc": "./static/iconfont/iconfont.ttf", "text": "\ue604" }] } } } }, { "path": "pages/list/list", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } }, { "path": "pages/shopcart/shopcart", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } }, { "path": "pages/my/my", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } } ]

二.如果要求三端一致

那么就必须使用自定义导航栏

1.App、H5使用原生导航,微信使用自定义导航

条件编译 + "navigationStyle": "custom"

"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages { "path": "pages/index/index", "style": { "navigationBarTitleText": "百年奥莱", "navigationBarBackgroundColor": "#FFFFFF", // #ifdef MP-WEIXIN "navigationStyle": "custom", // #endif "app-plus": { "titleNView": { "buttons": [{ "float": "left", "fontSrc": "./static/iconfont/iconfont.ttf", "text": "\ue637" }, { "float": "right", "fontSrc": "./static/iconfont/iconfont.ttf", "text": "\ue604" }] } } } }, { "path": "pages/list/list", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } }, { "path": "pages/shopcart/shopcart", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } }, { "path": "pages/my/my", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } } ]

vue页面也需要做相应处理

//index.vue <template> <view class="index"> <!-- #ifdef MP-WEIXIN --> <view class="status_bar"></view> <view class="wx-nav"> <view class="iconfont icon-fangdajing"> </view> 百年奥莱 <view class="iconfont icon-xiaoxi"> </view> </view> <!-- #endif --> <view class="f-active-color"> 首页 </view> <view class="iconfont icon-xiaoxi"> </view> </view> </template> <script setup lang="ts"> </script> <style scoped> .status_bar { height: var(--status-bar-height); width: 100%; } .wx-nav { text-align: center; height: 50rpx; width: 100%; line-height: 50rpx; display: flex; flex-direction: row; align-items: center; justify-content: space-between; } </style>

2.二种办法:使用uni-nav-bar组件

先要下载uni-nav-bar组件到uni_modules文件夹下

使用uni-nav-bar组件的插槽功能,或者直接使用本身的icon都可以

<template> <view class="index"> <view class="status_bar" :style="{'height':statusBarHeight + 'px'}"> </view> <view class="nav-bar" :style="{'width':isMP_WEIXIN?'74%':''}"> <uni-nav-bar dark :title="navTitle" :height="navBarHeight" @clickLeft="clickLeft" @clickRight="clickRight"> <template v-slot:left> <view class="iconfont icon-fangdajing"></view> </template> <template v-slot:right> <view class="iconfont icon-xiaoxi"></view> </template> </uni-nav-bar> </view> <view class="f-active-color"> 首页 </view> </view> </template> <script setup lang="ts"> import uniNavBar from "../../uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue"; import { onMounted, ref } from "vue"; const navTitle = ref('百年奥莱') const statusBarHeight = ref(50) const navBarHeight = ref(44) const isMP_WEIXIN = ref(false) const clickLeft = () => { console.log("点击了clickLeft"); } const clickRight = () => { console.log("点击了clickRight"); } onMounted(() => { uni.getStorage({ key: "statusBarHeight", success(res) { statusBarHeight.value = res.data } }) uni.getStorage({ key: "navBarHeight", success(res) { navBarHeight.value = res.data isMP_WEIXIN.value = true } }) }) </script> <style scoped> .status_bar { width: 100%; } .wx-nav { text-align: center; height: 50rpx; width: 100%; line-height: 50rpx; display: flex; flex-direction: row; align-items: center; justify-content: space-between; } .icon_font { font-size: 60rpx; } </style>

3.全部使用自定义导航(自己写一个自定义导航)

(1)pages.json中开启自定义导航

"pages": [ { "path": "pages/index/index", "style": { "navigationBarTitleText": "百年奥莱", "navigationBarBackgroundColor": "#FFFFFF", "navigationStyle": "custom", } }, { "path": "pages/list/list", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } }, { "path": "pages/shopcart/shopcart", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } }, { "path": "pages/my/my", "style": { "navigationBarTitleText": "", "enablePullDownRefresh": false } } ]

(2)封装一个navbar组件

//nav-bar.vue <template> <view class="nav-bar"> <view class="status" :style="{'height':statusBarHeight + 'px'}"> </view> <view class="nav" :style="{'height':navBarHeight + 'px'}"> <view class="left" v-if="props.withLeft"> <view class="slot"> <slot name="left"></slot> </view> <view class="default" @tap="onBackTap"> <image src="./arrow-left.png" mode="widthFix"></image> </view> </view> <view class="center"> {{props.title}} </view> <view class="right" v-if="withRight" @tap="onRightTap"> <view class="slot"> <slot name="right"></slot> </view> <view class="default"> <image src="./xiaoxi.png" mode="widthFix" class="icon"></image> </view> </view> </view> </view> </template> <script setup> import { onMounted, ref } from "vue"; const props = defineProps({ title: { type: String, default: "导航" }, withLeft: { type: Boolean, default: false }, withRight: { type: Boolean, default: false } }) let statusBarHeight = ref(35) let navBarHeight = ref(44) const emit = defineEmits(['clickLeft', 'clickRight']) const onBackTap = () => { console.log("点击了back"); uni.navigateBack() emit('clickLeft') } const onRightTap = () => { console.log("点击了right"); emit('clickRight') } onMounted(() => { uni.getStorage({ key: 'statusBarHeight', success: function(res) { statusBarHeight = res.data; //console.log('statusBarHeight', statusBarHeight); } }); uni.getStorage({ key: 'navBarHeight', success: function(res) { navBarHeight = res.data; console.log('navBarHeight', navBarHeight); } }); }) </script> <style scoped> /* #ifdef MP-WEIXIN */ .nav-bar { width: 76%; } /* #endif */ .nav { display: flex; color: #FFFFFFF; } .status { /* height: var(--status-bar-height); */ width: 100%; } .left, .right, .center { display: flex; justify-content: center; align-items: center; } .nav .left, .nav .right { width: 120rpx; } .nav .center { flex: 1; } .left .icon { width: 40rpx; height: 40rpx; } .default { display: none; } .slot:empty+.default { display: flex; } </style>

(3)index.vue中使用

//index.vue <template> <view class="index"> <nav-bar :title="navTitle" withLeft withRight> <template v-slot:left> <view class="iconfont icon-fangdajing icon_font"></view> </template> <template v-slot:right> <view class="iconfont icon-xiaoxi icon_font"></view> </template> </nav-bar> <view class="f-active-color"> 首页 </view> </view> </template> <script setup lang="ts"> import { ref } from "vue"; const navTitle = ref("百年奥莱") </script> <style scoped> .status_bar { height: var(--status-bar-height); width: 100%; } .wx-nav { text-align: center; height: 50rpx; width: 100%; line-height: 50rpx; display: flex; flex-direction: row; align-items: center; justify-content: space-between; } .icon_font { font-size: 60rpx; } </style>