uniapp开发微信小程序做自定义顶部导航栏
要求是顶部导航栏自定义,左边是返回按钮(如果有上一页的话)和首页按钮(常驻),过来是页面标题居中,右边不管是微信小程序默认的胶囊
查AI弄的,AI给的代码原生出错的,还得自己一点一点慢慢修改,步骤如下:
1. pages.json文件中设置全部页面都用自定义导
{
"pages": [
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
],
"globalStyle": {
"navigationStyle":"custom", //全部页面都用自定义导航
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
}
2. 建立全局组件components\navbar
<!-- components/navbar/navbar.vue -->
<template>
<view class="niunan_navbar" :style="{ height: navHeight + 'px', backgroundColor: bgColor, paddingTop:'55px' }">
<view :style="{display:'flex',width: availableWidth+'px'}">
<view style="display:flex;padding-left: 15rpx;">
<u-icon name="arrow-left" size="24" v-if="pages.length > 1" @click="goBack"></u-icon>
<u-line direction="column" :hairline="false" v-if="pages.length > 1" length="16" margin="0 8px"></u-line>
<u-icon name="home" size="24" @click="goHome"></u-icon>
</view>
<view style="flex:1;text-align: center;">{{title}}</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 页面标题(父组件传入)
title: {
type: String,
default: '默认标题'
},
// 导航栏背景色
bgColor: {
type: String,
default: '#ededed'
},
// 标题颜色
titleColor: {
type: String,
default: '#000000'
}
},
data() {
return {
statusBarHeight: 0, // 状态栏高度
navContentHeight: 44, // 导航栏内容高度(微信默认44px)
navHeight: 0, // 总高度=状态栏+内容区
availableWidth: 0, // 【重点】除去胶囊后的中间可用宽度
pages: [] // 页面栈
};
},
created() {
this.getSystemInfo();
this.pages = getCurrentPages(); // 获取当前页面栈
},
methods: {
// 获取系统信息(适配状态栏和胶囊按钮)
getSystemInfo() {
const systemInfo = uni.getSystemInfoSync();
const screenWidth = systemInfo.screenWidth; //屏幕宽度
console.log("屏幕宽度:",screenWidth)
this.statusBarHeight = systemInfo.statusBarHeight || 0;
// 也可以通过胶囊按钮位置更精确计算(可选)
const menuButton = uni.getMenuButtonBoundingClientRect();
console.log('胶囊:',menuButton)
if (menuButton) {
// 3. 计算导航栏内容高度(适配胶囊按钮垂直居中)
this.navContentHeight = menuButton.height + (menuButton.top - this.statusBarHeight) * 2;
// 胶囊右边留白 = 屏幕宽度 - 胶囊右边距
const rightGap = screenWidth - menuButton.right;
// 除去微信胶囊那一块的宽度
this.availableWidth = menuButton.left - rightGap;
} else {
// 兜底默认值(微信小程序一般不会走到这里)
this.navContentHeight = 44;
this.availableWidth = screenWidth - 16; // 假设左右各留白8px
}
// 导航栏总高度 = 状态栏高度 + 内容区高度
this.navHeight = this.statusBarHeight + this.navContentHeight;
},
// 返回上一页
goBack() {
uni.navigateBack();
},
// 跳转首页(根据首页是否为tabbar选择方法)
goHome() {
// 如果首页是tabbar页面,用switchTab
// uni.switchTab({
// url: '/pages/index/index'
// });
// 如果首页不是tabbar页面,用reLaunch(重启所有页面)
uni.reLaunch({
url: '/pages/tabbar/home'
});
}
}
};
</script>
<style scoped>
.niunan_navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
}
</style>
3. 每个页面都加入导航组件,created方法里计算组件距离顶部系统栏的位置
<template>
<view>
<navbar title="杏林荟萃"></navbar>
<view :style="{ paddingTop: navHeight + 'px' }">
这里是正文内容
</view>
</view>
</template>
<script>
export default {
data() {
return {
navHeight: 0, //正文内容距离顶部的高度
}
},
created() {
// 获取导航栏高度(也可以从组件通过事件传出,这里直接再获取一次)
const systemInfo = uni.getSystemInfoSync();
const menuButton = uni.getMenuButtonBoundingClientRect();
this.navHeight = systemInfo.statusBarHeight + (menuButton.height + (menuButton.top - systemInfo
.statusBarHeight) * 2);
}
</script>