uniapp开发微信小程序做自定义顶部导航栏

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>