Custom Navigation Bar Implementation for WeChat Mini Program in UniApp

Hiding the Native NavigationBar

To customize the navigation bar, first hide the native one. There are two approaches:

  1. Global Customization
    In the global configuration (e.g., manifest.json), set navigationStyle to custom:

    "globalStyle": {
      "navigationStyle": "custom"
    }
    
  2. Page-Specific Customization
    For individual pages, configure in the page’s style property:

    {
      "pages": [
        {
          "path": "pages/index/index",
          "style": {
            "navigationStyle": "custom" // Enable custom navigation for this page
          }
        }
        // Other pages...
      ]
    }
    

Encapsulating a Custom Navigation Bar Component

After setting navigationStyle to custom, the page’s top navigation must be built manually. Key challenges:

  • What is the correct height for the navigation bar?
  • How to avoid overlap with device notches or status icons?

Different phone models have varying navigation bar heights. To adapt to more devices, calculate the height dynamical:

  • Status Bar Height: Obtained via uni.getSystemInfo().
  • Capsule Button Info: Obtained via wx.getMenuButtonBoundingClientRect() (native component, units in px).

The formula for the navigation bar height:
navHeight = statusBarHeight + capsuleHeight + 2 * (capsuleTop - statusBarHeight)
(Where capsuleTop is the capsule’s top distance from the screen, and statusBarHeight is the status bar height.)

Implemantation Steps

1. Create a Custom Navigation Component (CustomNavbar)

Vue Tmeplate

<view class="custom-navbar" :style="{'background': bgColor, 'height': navHeight + 'px'}">
  <view :style="{'height': capsuleH + 'px', 'top': capsuleT + 'px'}" class="back-area">
    <view class="back-arrow" v-if="showBack" @click="goBack"></view>
  </view>
  <view class="title-text" :style="{ 'height': capsuleH + 'px', 'top': capsuleT + 'px' }">
    {{ pageTitle }}
  </view>
</view>

CSS Styles

.custom-navbar {
  width: 100%;
  position: fixed;
  top: 0;
  z-index: 99;
}
.back-area {
  position: absolute;
  left: 40rpx;
  z-index: 999;
  display: flex;
  align-items: center;
}
.back-arrow {
  width: 20rpx;
  height: 20rpx;
  border: 5rpx solid #FFFFFF;
  border-right-color: transparent;
  border-bottom-color: transparent;
  transform: rotate(-45deg);
}
.title-text {
  position: absolute;
  left: 0;
  right: 0;
  font-size: 28rpx;
  color: #FFFFFF;
  display: flex;
  align-items: center;
  justify-content: center;
}

JavaScript Logic

export default {
  props: {
    pageTitle: {
      type: String,
      default: 'Home'
    },
    bgColor: {
      type: String,
      default: 'linear-gradient(to right, #FF3413, #FF924D)'
    },
    showBack: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      capsuleT: '', // Distance from capsule to top
      capsuleH: '', // Capsule height
      navHeight: '' // Navigation bar height
    }
  },
  onLoad() {
    const app = getApp();
    this.capsuleT = app.globalData.menuButton.top;
    this.capsuleH = app.globalData.menuButton.height;
    const statusBarH = app.globalData.system.statusBarHeight;
    this.navHeight = (this.capsuleT - statusBarH) * 2 + this.capsuleH + statusBarH;
  },
  methods: {
    goBack() {
      uni.navigateBack({ delta: 1 });
    }
  }
}

2. Global Initialization in app.vue

In app.vue, fetch system and capsule button info once:

export default {
  globalData: {
    system: {},
    menuButton: {}
  },
  onLaunch() {
    // Fetch system info
    uni.getSystemInfo({
      success: (res) => {
        this.globalData.system = res;
      }
    });
    // Fetch capsule button info
    this.globalData.menuButton = wx.getMenuButtonBoundingClientRect();
  }
}

3. Using the Component

Import and use the CustomNavbar component in any page requiring a custom navigation bar.

Tags: UniApp WeChat Mini Program Custom Navigation Bar Component Encapsulation Responsive Design

Posted on Sun, 07 Jun 2026 17:00:06 +0000 by Domestics