• 微信小程序自定义顶部导航栏


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

    前言

    现成轮子网上很多,但是想实现自己的需求,还得自己再造一遍轮子,有一篇文章写的很好:微信小程序自定义navigationBar

    效果图

    效果图

    亮点

    1. ✅保证安卓IOS显示效果一致
    2. 拓展🉑️同时显示返回上一页返回首页
    3. 点击标题🉑️返回顶部
    4. 预留slot进行拓展

    代码

    index.js

    Component({
      properties: {
        title: { // 标题
          type: String,
          value: 'hello world',
        },
        showGoBack: { // 显示返回按钮
          type: Boolean,
          value: false,
        },
        showHome: { // 显示返回主页按钮
          type: Boolean,
          value: false,
        },
        position: { // 是否开启绝对定位
          type: Boolean,
          value: false,
        },
        bgColor: { // 导航栏背景颜色
          type: String,
          value: 'transparent',
        },
        titleColor: { // 导航栏标题颜色
          type: String,
          value: '#000000',
        },
        showSlot: { // 是否开启slot
          type: Boolean,
          value: false,
        },
        showBlankBlock: { // 是否开启空白块占位
          type: Boolean,
          value: false,
        },
      },
    
      lifetimes: {
        async attached() {
          const systemInfo = await wx.getSystemInfo()
    
          const {
            statusBarHeight,
            windowWidth
          } = systemInfo
    
          const rightCapsule = wx.getMenuButtonBoundingClientRect()
    
          const {
            top,
            right,
            width,
            height
          } = rightCapsule
    
          const navBarYPadding = top - statusBarHeight
    
          const navBarXPadding = windowWidth - right
    
          const navBarHeight = height + (navBarYPadding * 2)
    
          const navBarBodyHeight = height
    
          const rightCapsuleWidth = width
    
          const styleData = `--bgColor: ${this.properties.bgColor};
            --statusBarHeight: ${statusBarHeight}px;
            --navBarHeight: ${navBarHeight}px;
            --navBarBodyHeight: ${navBarBodyHeight}px;
            --navBarYPadding: ${navBarYPadding}px;
            --navBarXPadding: ${navBarXPadding}px;
            --rightCapsuleWidth: ${rightCapsuleWidth}px;
            --rightCapsuleHeight: ${navBarBodyHeight}px;
            --rightCapsuleRadius: ${navBarBodyHeight / 2}px;
            --titleColor: ${this.properties.titleColor};
            `
    
          const backIconUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAY9JREFUWEfFl88rBVEUgL/3Lyj/lbLzI6UoSlGEKAsWihBFKUpRFspCSSkWxIJYKIqFYqFYkJWsJJ06V6ep9969c+e9O6upmeb7zo85c6ZE4qOUmE+tBBo0sM9qAdZCYAqYVHAXsFlJomiBaWDCAAUuEmWPIgVmgTFD+gWagMN6CMwDIwb0DbQD+/XogSVg0ICk8QR+VA0u12NLsAL0G9Ab0Aac+cBjBVaBPgN6VviVLzxGYB3oMaAHhd+GwPMKbADdBnQDtAKPofA8AltApwFdAi3ASx54qMA20GFApwp/zwsPEdjRNDuWDBeJ/CsG7iuwAAwb0J7Cf2LhvgKjwFxKAWEnLYELPtuEJ1qKj5hShI7i7Gt4oc1Zl9fQBZp0EDmJNaDXpP5eR/FdaDlCS2Cfn/0YPanEdYhEjIBwloEBA3xViXNfiVgB4SwCQwYoC4nsBMc+EkUICCfpSuYCnQHGTdSylDYDB5UyUVQGHCO7lu/qsCrrULSAgJL+mLhIG/Wk6q5Qiwz4NP//PckF/gCIUUwhlNMi4AAAAABJRU5ErkJggg=='
    
          const homeIconUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAidJREFUWEft10+oD1EUwPHPW2BlI5KdkiQ7C2+l2LDxr+SxIJSQEiURCyz0ZEFECPm78KdeSVYSKcXKBjslxYJkJRtJ53VH86aZ38xv3u+3+53Vnbn3nPO95557zsyQ9rIJuzAdj3GijamhNkrYjUsF3TM40K29NgCHMZocHcXf3PNV7OwGoluAUziUHOzD+TTeg4tpfA9b8KcJSDcAV3K724HrBQebcQ3T8CRB/KyDaAIwFXcwgt/YjvsVhtckiFl4mSA+d4KoA5iN21iB78l57K6TLMUNzMPbBPG+SqETwILkfAk+IUL8qi6kaX4h7mIxPibd12W6VQDDKezz8Q5x5yt3UQE1Ew+xDN8SxNPi2jKAlcl5nOMbrMeXhjsvW/YIkRuRPxHFsfyiIsDG5HwKnmEtfk3CeaYaSRzOQ7bhVjaRB4iyejlNBPW6HjjOmziL/enFXlyIcQYQxSWKTEjQBWU/5AhOJsMxHg2AVamZxPtzOcp+AITNKNVR1EJWB8BxHCvpZvG+l1K0N+4zACLcUTjy8gLLe+kdz9OVzJsdyXJgAxalmSDrJ0D23fAAH4rXMIpGkPYTICIb9selDUAc2daK44kbdLNiLjuCSQEcxOma3IgQlyVwTwDyRso4Oh1fTwHKekhd/gwABhEYRGAQgUYRmIEfNaW2qlHNwdcGLXxCESuraNFsoiXPLTEWzqPW/+9mhTXxfxitPb6oixJw8fM6oU/8A8+oq0Iv6rN4AAAAAElFTkSuQmCC'
    
          this.setData({
            statusBarHeight,
            navBarHeight,
            navBarBodyHeight,
            navBarYPadding,
            navBarXPadding,
            rightCapsuleWidth,
            styleData,
            backIconUrl,
            homeIconUrl,
          })
        },
      },
    
      data: {
        statusBarHeight: 20, // 状态栏高度
        navBarHeight: 40, // 导航栏高度
        navBarBodyHeight: 32, // 导航栏内容高度
        navBarYPadding: 4, // 导航栏Y轴内间距
        navBarXPadding: 8, // 导航栏X轴内间距
        rightCapsuleWidth: 87, // 右边胶囊宽度
        styleData: '', // 样式变量
        backIconUrl: '', // 返回icon
        homeIconUrl: '', // 主页icon
      },
    
      methods: {
        goBack() {
          // console.log('goBack');
    
          const pages = getCurrentPages()
    
          // 单曲页面栈小于等于一个页面,直接返回首页
          if (pages.length <= 1) {
            this.goHome()
          } else {
            wx.navigateBack()
          }
        },
    
        goHome() {
          // console.log('goHome');
    
          // 小程序中页面栈最多十层
          // 返回的页面数,如果 delta 大于现有页面数,则返回到首页。
          wx.navigateBack({
            delta: 10
          })
        },
    
        backTop() {
          wx.pageScrollTo({
            scrollTop: 0,
            duration: 300
          })
        },
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138

    index.wxml

    <view style="{{styleData}}">
    
      <view class="c-navbar {{position ? 'c-navbar--position' : ''}}">
        
        <view class="c-navbar__status-bar">view>
    
        
        <view class="c-navbar__body" wx:if="{{!showSlot}}">
          
          <view class="c-navbar__body__left">
            <view class="c-navbar__body__left__back" wx:if="{{showGoBack && (!showHome)}}" bindtap="goBack">
              <image src="{{backIconUrl}}" class="c-navbar__body__icon c-navbar__body__left__icon--back">image>
              <text>返回text>
            view>
    
            <view class="c-navbar__body__left__home" wx:if="{{showGoBack && showHome}}">
              <view class="c-navbar__body__left__home__back" bindtap="goBack">
                <image src="{{backIconUrl}}" class="c-navbar__body__icon c-navbar__body__left__home--back">image>
              view>
              <view class="c-navbar__body__left__home--division">view>
              <view class="c-navbar__body__left__home__home" bindtap="goHome">
                <image src="{{homeIconUrl}}" class="c-navbar__body__icon c-navbar__body__left__home--home">image>
              view>
            view>
          view>
    
          
          <view class="c-navbar__body__title" bindtap="backTop">
            {{title}}
          view>
    
          
          <view class="c-navbar__body__right">view>
        view>
    
        
        <view class="c-navbar__body" wx:if="{{showSlot}}">
          <view class="c-navbar__body--slot">
            <slot>slot>
          view>
    
          
          <view class="c-navbar__body__right">view>
        view>
      view>
    
      
      <view class="c-blank-block" wx:if="{{showBlankBlock}}">view>
    view>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    index.wxss

    .c-navbar {
        position: -webkit-sticky;
        position: sticky;
        top: 0;
        left: 0;
        z-index: 9999;
        width: 100vw;
        box-sizing: border-box;
    
        background-color: var(--bgColor);
    }
    
    .c-navbar--position {
        position: fixed;
    }
    
    .c-navbar__status-bar {
        width: 100vw;
        height: var(--statusBarHeight);
    }
    
    .c-navbar__body {
        width: 100vw;
        height: var(--navBarHeight);
        padding: 0 var(--navBarXPadding);
        overflow: hidden;
        box-sizing: border-box;
        overflow: hidden;
    
        display: -webkit-flex;
        display: flex;
        /* -webkit-justify-content: center;
        justify-content: center; */
        -webkit-align-items: center;
        align-items: center;
        flex-wrap: wrap;
    }
    
    .c-navbar__body__left {
        width: var(--rightCapsuleWidth);
        height: var(--rightCapsuleHeight);
        box-sizing: border-box;
        font-size: 16px;
        font-weight: 500;
    
        display: -webkit-flex;
        display: flex;
        -webkit-justify-content: center;
        justify-content: center;
        -webkit-align-items: center;
        align-items: center;
        flex-wrap: wrap;
    }
    
    .c-navbar__body__title {
        box-sizing: border-box;
        flex: 1;
        padding: 0 var(--navBarXPadding);
    
        text-align: center;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    
        color: var(--titleColor);
        font-size: 18px;
        font-weight: 500;
    }
    
    .c-navbar__body__right {
        width: var(--rightCapsuleWidth);
        height: var(--rightCapsuleHeight);
    }
    
    .c-navbar__body__icon {
        display: inline-block;
        width: 20px;
        height: 20px;
    }
    
    .c-navbar__body__left__back {
        height: 100%;
        background-color: rgba(255, 255, 255, .6);
        border: 1px solid rgba(0, 0, 0, .1);
        border-radius: var(--rightCapsuleRadius);
        box-sizing: border-box;
        padding: 0 calc(var(--navBarXPadding) * 2);
    
        display: -webkit-flex;
        display: flex;
        -webkit-justify-content: center;
        justify-content: center;
        -webkit-align-items: center;
        align-items: center;
        flex-wrap: wrap;
    }
    
    .c-navbar__body__left__icon--back {
        margin-left: -5px;
    }
    
    .c-navbar__body__left__home {
        position: relative;
    
        width: 100%;
        height: 100%;
        background-color: rgba(255, 255, 255, .6);
        border: 1px solid rgba(0, 0, 0, .1);
        border-radius: var(--rightCapsuleRadius);
        box-sizing: border-box;
    
        display: -webkit-flex;
        display: flex;
    }
    
    .c-navbar__body__left__home__back {
        flex: 1;
    
        display: -webkit-flex;
        display: flex;
        -webkit-justify-content: center;
        justify-content: center;
        -webkit-align-items: center;
        align-items: center;
        flex-wrap: wrap;
    }
    
    .c-navbar__body__left__home__home {
        flex: 1;
    
        display: -webkit-flex;
        display: flex;
        -webkit-justify-content: center;
        justify-content: center;
        -webkit-align-items: center;
        align-items: center;
        flex-wrap: wrap;
    }
    
    .c-navbar__body__left__home--back {
        width: 22px;
        height: 22px;
        box-sizing: border-box;
    }
    
    .c-navbar__body__left__home--home {
        width: 19px;
        height: 19px;
        box-sizing: border-box;
    }
    
    .c-navbar__body__left__home--division {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    
        width: 1px;
        height: 20px;
        background-color: rgba(0, 0, 0, .1);
    }
    
    .c-navbar__body--slot {
        flex: 1;
    }
    
    .c-blank-block {
        width: 100vw;
        height: calc(var(--statusBarHeight) + var(--navBarHeight));
        background-color: transparent;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171

    index.json

    {
        "component": true,
        "usingComponents": {}
    }
    
    • 1
    • 2
    • 3
    • 4

    属性

    属性描述默认值
    title标题hello world
    showGoBack显示返回按钮false
    showHome显示返回主页按钮false
    position是否开启绝对定位false
    bgColor导航栏背景颜色white
    titleColor导航栏标题颜色#000000
    showSlot是否开启slotfalse
    showBlankBlock是否开启空白块占位false

    使用

    index.json

    {
        "usingComponents": {
            "wmp-navbar": "@chenbz/wmp-navbar"
        },
        "navigationStyle": "custom"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    index.wxml

    
      
    
    
    • 1
    • 2
    • 3

    npm

    组件已打包发布到npm,欢迎移步至@chenbz/wmp-navbar

  • 相关阅读:
    C语言核心知识点总结
    Linux编程知识之GLIB的GOption接口函数
    【NodeJs篇】npm和包
    认证双软需要什么样的基本条件?
    TensorFlow
    android上架之获取平台公钥、签名 MD5 值
    Eclipse插件开发demo
    “蔚来杯“2022牛客暑期多校训练营5 E题: Fraction Game
    Activiti7工作流 二【Activiti7入门、Activiti7进阶】
    三、Go环境安装
  • 原文地址:https://blog.csdn.net/weixin_42863549/article/details/126449900