uniapp custom navigation bar

Customized navigation bar

Modify pages.json

Set navigateionStyle to custom in pages.json

image-20231013124909430

New systemInfo.js

systemInfo.js is used to obtain the model system information of the current device and place it in the common directory.

image-20231013130951574

/**
 * This js file manages model system information about the current device
 */
const systemInfo = function() {<!-- -->
/****************** System information common to all platforms ************************/
//Device system information
let systemInfomations = uni.getSystemInfoSync()
//Model adaptation proportion coefficient
let scaleFactor = 750 / systemInfomations.windowWidth
//Current model-screen height
let windowHeight = systemInfomations.windowHeight * scaleFactor //rpx
//Current model-screen width
let windowWidth = systemInfomations.windowWidth * scaleFactor //rpx
//Status bar height
let statusBarHeight = (systemInfomations.statusBarHeight) * scaleFactor //rpx
 
// Navigation bar height Note: This navigation bar height is only valid for WeChat applet. For other platforms, if you want to customize the navigation bar, please use: status bar height + custom text height
let navHeight = 0 //rpx
\t
/****************** WeChat Mini Program Head Capsule Information ********************/
// #ifdef MP-WEIXIN
const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
//Capsule height
let menuButtonHeight = menuButtonInfo.height * scaleFactor //rpx
// Capsule width
let menuButtonWidth = menuButtonInfo.width * scaleFactor //rpx
//Coordinates of the upper boundary of the capsule
let menuButtonTop = menuButtonInfo.top * scaleFactor //rpx
//Coordinates of the right boundary of the capsule
let menuButtonRight = menuButtonInfo.right * scaleFactor //rpx
//Coordinates of the lower boundary of the capsule
let menuButtonBottom = menuButtonInfo.bottom * scaleFactor //rpx
//Coordinates of the left boundary of the capsule
let menuButtonLeft = menuButtonInfo.left * scaleFactor //rpx
 
// Navigation bar height in WeChat applet = capsule height + (top distance - status bar height) * 2
navHeight = menuButtonHeight + (menuButtonTop - statusBarHeight) * 2
// #endif
 
 
// #ifdef MP-WEIXIN
return {<!-- -->
scaleFactor,
windowHeight,
windowWidth,
statusBarHeight,
menuButtonHeight,
menuButtonWidth,
menuButtonTop,
menuButtonRight,
menuButtonBottom,
menuButtonLeft,
navHeight
}
// #endif
 
// #ifndef MP-WEIXIN
return {<!-- -->
scaleFactor,
windowHeight,
windowWidth,
statusBarHeight
}
// #endif
}
 
export {<!-- -->
systemInfo
}

New component HeadNav

<!--
 Notice:
 1. When passing in width or height, if it is Number data, the value passed in is the px size. There is no need to bring the unit, and the component automatically calculates it.
 2. When using this navigation bar, it is recommended to pass in the navigation bar height specified by the UI. This height is only valid for other platforms except WeChat mini programs. The navigation bar height of WeChat mini programs is calculated by the component.
-->
<template>
<view :style="{height:navHeight + 'rpx'}">
<!-- WeChat applet head navigation bar -->
<!-- #ifdef MP-WEIXIN -->
<view class="wx-head-mod" :style="{height:navHeight + 'rpx',backgroundColor:navBackgroundColor}">
<view class="wx-head-mod-nav" :style="{height:navigationBarHeight + 'rpx',top:statusBarHeight + 'rpx'}">
<view class="wx-head-mod-nav-content"
:style="{height:customHeight + 'rpx',justifyContent:textAlign === 'center'?'center':'left'}">
<!-- Text area -->
<view class="wx-head-mod-nav-content-mian"
:style="{width:navTextWidth,lineHeight:customHeight + 'rpx',paddingLeft:textPaddingLeft*scaleFactor + 'rpx',fontSize:fontSize*scaleFactor + 'rpx',fontWeight:fontWeight,color: titleColor}">
{<!-- -->{textContent}}
</view>
<!-- Back button -->
<view class="wx-head-mod-nav-content-back" :style="{display:isBackShow?'flex':'none'}"
@click="backEvent">
<view class="wx-head-mod-nav-content-back-img"
:style="{width:backImageWidth*scaleFactor + 'rpx',height:backImageHeight*scaleFactor + 'rpx'}">
<image :src="backImageUrl" mode="" style="width: 100%;height: 100%;"></image>
</view>
</view>
</view>
</view>
</view>
<!-- #endif -->
 
<!-- Other devices except WeChat applet -->
<!-- #ifndef MP-WEIXIN -->
<view class="other-head-mod"
:style="{height:navHeightValue*scaleFactor + statusBarHeight + 'rpx',backgroundColor:navBackgroundColor}">
<view class="other-head-mod-mian"
:style="{height:navHeightValue*scaleFactor + 'rpx',justifyContent:textAlign === 'center'?'center':'left'}">
<!-- Back button -->
<view class="other-head-mod-mian-back" v-show="isBackShow" @click="backEvent">
<view class="other-head-mod-mian-back-img"
:style="{width:backImageWidth*scaleFactor + 'rpx',height:backImageHeight*scaleFactor + 'rpx'}">
<image :src="backImageUrl" mode="" style="width: 100%;height: 100%;"></image>
</view>
</view>
<!-- Title -->
<view class="other-head-mod-mian-title" :style="{width:windowWidth - 184 + 'rpx',lineHeight:navHeightValue*scaleFactor + 'rpx',
paddingLeft:textPaddingLeft*scaleFactor + 'rpx',fontSize:fontSize*scaleFactor + 'rpx',
fontWeight:fontWeight,color:titleColor}">
{<!-- -->{textContent}}
</view>
</view>
</view>
<!-- #endif -->
</view>
</template>
 
<script>
const app = getApp()
import {systemInfo} from '@/pages/v2/acommon_js/system_info.js'
export default {
name: "HeadView",
props: {
// Text area position left: left center: center
textAlign: {
type: String,
default: 'center'
},
//Text area content
textContent: {
type: String,
default: 'Hahahahahahahahahahahahahahahahaha it's easy to borrow and return'
},
//The distance of the text area from the left
textPaddingLeft: {
type: Number,
default: 16
},
// Do you need a return button?
isBackShow: {
type: Boolean,
default: true
},
// Text area font size
fontSize: {
type: Number,
default: 20 //px
},
// Text area font thickness
fontWeight: {
type: Number,
default: 700
},
// Text area return button image width
backImageWidth: {
type: Number,
default: 12 //px
},
// Text area return button image height
backImageHeight: {
type: Number,
default: 24 //px
},
// Return button icon path
backImageUrl: {
type: String,
default: '/static/v2/aichat/ai_robot.png'
},
//The overall background color of the navigation bar
navBackgroundColor: {
type: String,
default: '#2476F9'
},
//Title font color
titleColor: {
type: String,
default: '#ffffff',
},
 
/******** h5 side, the app side needs to pass in the custom navigation bar height *******/
navHeightValue: {
type: Number,
default: 44 //px
}
},
computed: {
// Text area width
navTextWidth() {
if (this.textAlign === 'center') {
return (this.windowWidth - (this.windowWidth - this.menubarLeft) * 2) + 'rpx'
} else {
return this.menubarLeft + 'rpx'
}
},
// text area paddingLeft
textPaddingleft() {
if (this.textAlign === 'center') {
return '0'
} else {
return this.textPaddingLeft + 'rpx'
}
}
},
data() {
return {
statusBarHeight: app.globalData.statusBarHeight, //status bar height
navHeight: app.globalData.navHeight, //The overall height of the head navigation bar
navigationBarHeight: app.globalData.navigationBarHeight, //Navigation bar height
customHeight: app.globalData.customHeight, //Capsule height
scaleFactor: app.globalData.scaleFactor, //scale factor
menubarLeft: app.globalData.menubarLeft, //left of capsule positioning
windowWidth: app.globalData.windowWidth * app.globalData.scaleFactor
};
},
methods: {
backEvent() {
uni.navigateBack({
delta: 1
})
}
},
created() {
/* Get device information */
const SystemInfomations = systemInfo()
/* Common platform */
this.statusBarHeight = SystemInfomations.statusBarHeight //Status bar height
this.scaleFactor = SystemInfomations.scaleFactor //Scale factor
this.windowWidth = SystemInfomations.windowWidth //The screen width of the current device
/* WeChat mini program platform */
// #ifdef MP-WEIXIN
this.navHeight = SystemInfomations.navHeight + SystemInfomations.statusBarHeight //The total height of the head navigation bar
this.navigationBarHeight = SystemInfomations.navHeight //Height of the head navigation bar
this.customHeight = SystemInfomations.menuButtonHeight //Capsule height
this.menubarLeft = SystemInfomations.menuButtonLeft //The distance between the left border of the capsule and the upper left corner
// #endif
\t\t\t
console.log("this.navHeight:", this.navHeight)
}
}
</script>
 
<style>
/* #ifdef MP-WEIXIN */
.wx-head-mod {
box-sizing: border-box;
width: 100%;
position: fixed;
top: 0;
left: 0;
}
 
.wx-head-mod-nav {
box-sizing: border-box;
width: 100%;
position: absolute;
left: 0;
display: flex;
justify-content: center;
align-items: center;
 
}
 
.wx-head-mod-nav-content {
box-sizing: border-box;
width: 100%;
display: flex;
justify-content: left;
align-items: center;
position: relative;
}
 
/* text area */
.wx-head-mod-nav-content-mian {
box-sizing: border-box;
height: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
 
/* Back button */
.wx-head-mod-nav-content-back {
box-sizing: border-box;
width: 60rpx;
height: 100%;
/* background-color: aqua; */
position: absolute;
top: 0;
left: 32rpx;
display: flex;
align-items: center;
justify-content: left;
}
 
.wx-head-mod-nav-content-back-img {
box-sizing: border-box;
}
 
/* #endif */
 
/* #ifndef MP-WEIXIN */
.other-head-mod {
box-sizing: border-box;
width: 100%;
position: fixed;
top: 0;
left: 0;
}
 
.other-head-mod-mian {
box-sizing: border-box;
width: 100%;
display: flex;
align-items: center;
justify-content: left;
position: absolute;
left: 0;
bottom: 0;
}
 
/* Back button */
.other-head-mod-mian-back {
box-sizing: border-box;
height: 100%;
width: 60rpx;
position: absolute;
left: 32rpx;
top: 0;
display: flex;
align-items: center;
}
 
/* Title */
.other-head-mod-mian-title {
box-sizing: border-box;
height: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
 
/* #endif */
</style>

Use

Introduce components and use

<template>
<view>
<HeadNav text-content="Test navigation bar" nav-background-color="#fff"></HeadNav>
aaa
</view>
</template>

<script>
import HeadNav from '@/components/HeadNav.vue'
export default {
components: {
HeadNav
},
data() {
return {
title: 'Hello',
}
},
onLoad() {
},
methods: {
\t\t\t
}
}
</script>

<style>
body {
background-color: aliceblue;
}
</style>

If you need to define the color of the status bar foreground font, you can set navigationBarTextStyle. You can only set white or black

{<!-- -->
"pages": [
{<!-- -->
"path": "pages/index/Index",
"style": {<!-- -->
"navigationBarTextStyle": "black"
}
}
],
"globalStyle": {<!-- -->
"navigationStyle": "custom",
"backgroundColor": "#F8F8F8"
\t\t
},
"uniIdRouter": {<!-- -->}
}

Effect

image-20231013134547024

uview navigation bar usage

Introduce uview according to the documentation

Navbar custom navigation bar | uView 2.0 (uviewui.com)

Use u-navvar

<template>
<view>
<!-- 2.0.19 supports autoBack, the default is false -->
<u-navbar title="Personal Center" @rightClick="rightClick" :autoBack="true">
</u-navbar>
</view>
</template>

<script>
export default {
components: {

},
data() {
return {
title: 'Hello',
}
},
onLoad() {},
methods: {
rightClick() {
console.log('rightClick');
},
leftClick() {
console.log('leftClick');
}
}
}
</script>

<style>
body {
background-color: aliceblue;
}
</style>

Effect

image-20231013141209926