微信原生小程序自定义顶部导航

都2023了,自定义顶部导航应该不是什么新鲜事了,这里只是简单记录下
微信自己也提供了自定义顶部导航navigation-bar,大概看了下,可配置的也不少,所以看需求了,如果简单可以采用微信提供的,老规矩,先看效果
微信原生小程序自定义顶部导航_第1张图片

1、补充几个前置知识

  1. 状态栏高度(getSystemInfoSync),就是手机顶部网络那块的高度
  2. 胶囊位置信息(getMenuButtonBoundingClientRect),右边那个像胶囊一样的东西,通过它我们可以知道高度,计算出右边的padding
    微信原生小程序自定义顶部导航_第2张图片
    综上可知,整导航栏的高度其实是 1 所在区域 = 状态栏高度 + 胶囊高度 + ( 胶囊距离顶部 - 状态栏高度 ) * 2

因为,胶囊和状态栏之间还有一定间隙,所以完整的高度需要 胶囊距离顶部 - 状态栏高度

2、实现

首先需要知道上面说的那几个位置信息,思路分析

  1. 通常这些信息在小程序启动的时候获取一次就行了,所以我们需要做两手准备,如果全局里面没有,则导航组件再自己获取一次
  2. 如果没有获取到,应该有默认值(这时候样式肯定有不好看,不过没办法~)
  3. 顶部一般是定位固定的,所以用了导航组件后,应该有一个盒子用于占位补充定位导致塌陷的高度

3、完整代码如下

js如下

// component/navBar/navBar.js
const app = getApp()
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    // 标题
    title: {
      type: String,
      value: ''
    },
    // 是否需要返回
    hasBack: {
      type: Boolean,
      value: false
    },
    // 背景色
    bgc: {
      type: String,
      value: 'linear-gradient(to top, #96fbc4 0%, #f9f586 100%)'
    },
    // 是否固定
    isFixed: {
      type: Boolean,
      value: true
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    navInfo: {
      paddingLeft: 0, 
      paddingTop: 0,
      navHeight: 0 
    },
  },
  /**
   * 生命周期钩子
   * **/ 
  lifetimes: {
    created() {
      const { getSystemInfoSync, menuInfo} = app.globalData
      if(!Object.keys(getSystemInfoSync).length || !Object.keys(menuInfo).length) {
        console.warn('没有胶囊位置信息,重新获取中')
        this.customNavBarInfo()
      }
    },
    attached() {
      // 计算导航高度信息
      this.getNavBarInfo()
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    /**
     * 计算导航高度信息
     * **/ 
    getNavBarInfo() {
      // 防止没有获取到位置信息
      let navInfo = {
        paddingLeft: 7, // 默认胶囊距离屏幕右边的距离
        paddingTop: 20,// 默认
        navHeight: 44 // 默认导航栏高度
      }
      if(Object.keys(app.globalData.menuInfo).length && Object.keys(app.globalData.getSystemInfoSync).length) {
        const { top,height,right,width } = app.globalData.menuInfo
        const { statusBarHeight,windowWidth } = app.globalData.getSystemInfoSync
        navInfo = {
          paddingLeft: windowWidth - right, 
          paddingTop: statusBarHeight,
          navHeight: height + ( top - statusBarHeight ) * 2,
          menuWidth: width
        }
      }
      this.setData({
        navInfo
      })
    },
    /**
     * 获取胶囊位置信息
     * **/ 
    customNavBarInfo() {
      app.globalData.menuInfo = wx.getMenuButtonBoundingClientRect()
      app.globalData.getSystemInfoSync = wx.getSystemInfoSync()
    },
  }
})

css如下

.nav{
  display: flex;
  align-items: center;
}
// 这是笔者写一个宽度,需要根据自己情况调整
.left{
  width: 80rpx;
}
.custom-nav{
  z-index: 999;
  top: 0;
  right: 0;
  left: 0;
}

通常在app.js里面提前获取一次

App({
  onLaunch() {
    this.globalData.menuInfo = wx.getMenuButtonBoundingClientRect() || {}
    this.globalData.getSystemInfoSync = wx.getSystemInfoSync() || {}
  },
  globalData: {
    // 完整胶囊信息
    menuInfo: {},
    // 完整系统信息
    getSystemInfoSync: {},
  }
})

你可能感兴趣的:(微信,小程序)