微信小程序/uni-app中自定義頂部導航欄

一、項目目錄結構

說明:

1、components目錄用於存放自定義組件,bar是一個自定義組件,封裝了小程序頂部自定義導航欄。

        1>由於頂部導航欄大多頁面都需要,所以最好封裝成一個組件,直接引入,這也就引發了第二個需求。

        2>有時,在一個項目中,有些頁面的導航欄可能不一樣,所以此時我們應該儘可能的考慮到需求,然後封裝,在頁面更改值來達到不同的導航欄需求。

2、pages下存放頁面。

3、小程序自定義組件中不能使用app.wxss中的樣式,所以組件中共用的樣式、iconfont圖標單獨放在一個wxss文件中,然後直接引入即可~

 

二、版本

此次會給出2個版本的自定義導航欄

      1、微信小程序版本的     源碼下載:https://github.com/Syleapn/wx-custom-navigation

      2、uni-app版本的    源碼下載:https://github.com/Syleapn/uni-app-custom-navigation-

     其實兩者差不多,只是寫法上稍微有點區別,考慮到大多小夥伴初次對微信小程序熟悉,那本次就以微信小程序版本爲例剖析,uni-app直接貼出代碼或放到git上面下載!

 

三、分析

1、小程序自定義導航欄知識點補充

      微信小程序導航欄:由狀態欄與標題欄組成

      除了狀態欄與右上角膠囊外,其他區域都可由開發者控制,

      狀態欄高度:由系統信息獲取:statusBarHeight

      標題欄高度:ios:44px android:48px

      得到狀態欄與標題欄的高度後我們可以自定義微信小程序導航欄,從而達到項目需求。

2、圖片展示

更多相關或微信小程序設計指南請點擊這裏:https://developers.weixin.qq.com/miniprogram/design/

 

四、實現過程分析

1、先進行自定義導航欄封裝(bar文件)

bar.wxml



<!-- 微信小程序導航欄:由狀態欄與標題欄組成
			除了狀態欄與右上角膠囊外,其他區域都可由開發者控制,
			狀態欄高度:由系統信息獲取:statusBarHeight
			標題欄高度:ios:44px android:48px
			得到狀態欄與標題欄的高度後我們可以自定義微信小程序導航欄,從而達到項目需求 -->



<!-- 說明:
1、第一種情況:爲了便於說明導航欄的組成,添加了一個標籤,“狀態欄”所在的這個標籤
在web前端開發中,通常情況下,當我們自定義頂部導航欄時,要進行fixed,這樣會脫離標準流,導致後面的正文一部分覆蓋在導航欄下面
,通常的做法是:
把正文距離頂部向下移動導航欄高度的距離。此處爲了不向父組件傳值,直接在子組件(自定義導航欄)中解決這個問題,採用另一種思路。
就是添加一個額外的標籤,結合css樣式達到相同的目的。這個額外的標籤可以包裹在整個導航欄外面(像第一種與第三種情況),
也可以與導航欄平級(第二種情況)

2、終極情況:換繁爲簡,後續可以採用第二或第三種方案去實現自定義導航欄!
 -->


<!--第一種情況  -->
<!-- 額外標籤 -->
<view style="height: {{titleBarHeight}};padding-top:{{statusBarHeight}}">
  <!--導航欄  -->
  <view class="bar-view">
    <!-- 狀態欄 -->
    <view class="weight statuColumn" style="height: {{statusBarHeight}}">狀態欄</view>
    <!-- 標題欄 -->
    <view class="titleColumn" style="height:{{titleBarHeight}};background-color: {{nav.bg}}">
      <text class="iconfont leftArrow titleColumn-back weight" style="border:{{nav.color}}" wx:if="{{nav.isdisPlayNavTitle}}" bindtap="back"></text>
      <view class="titleColumn-title weight">{{nav.navTitle}}</view>
    </view>
  </view>
</view>



<!-- 第二種情況 -->
<!-- 導航欄 -->
<view class="header" style="height:{{titleBarHeight}};padding-top:{{statusBarHeight}};background-color:{{nav.bg}}">
     <text class="iconfont leftArrow header-back weight" style="border:{{nav.color}}" wx-if="{{nav.isdisPlayNavTitle}}" bindtap="back"></text>
     <view class="header-title weight">{{nav.navTitle}}</view>
</view>
<!-- 額外標籤 -->
<view style="height:{{titleBarHeight}};padding-top:{{statusBarHeight}}"></view>



<!-- 第三種情況 -->
<view  style="height:{{titleBarHeight}};padding-top:{{statusBarHeight}}">
  <view class="header" style="height:{{titleBarHeight}};padding-top:{{statusBarHeight}};background-color: {{nav.bg}}">
    <text class="iconfont leftArrow header-back weight" style="border:{{nav.color}}" wx:if="{{nav.isdisPlayNavTitle}}" bindtap="back"></text>
    <view class="header-title weight">{{nav.navTitle}}</view>
  </view>
</view>

bar.js

Component({
  properties:{
    nav:{
      type:Object
    }
  },
  data:{
    statusBarHeight: 0, //狀態欄初始化
    titleBarHeight: 0, //標題欄初始化
  },

  ready: function () {
    var that = this;
    wx.getSystemInfo({
      success: function (res) {
        // model設備型號
        // iOS
        // 標題欄高度
        if (res.model.indexOf('iPhone') !== -1) {
          that.setData({
            titleBarHeight: 44 + 'px'
          })
        } else {
          // android
          that.setData({
            titleBarHeight: 48 + 'px'
          })
        }
        
        // 狀態欄高度
        that.setData({
          statusBarHeight: res.statusBarHeight + 'px'
        })
      },

    })
  }
})

bar.wxss

	
  @import '/iconfont/font.wxss';

  /* ****************** 第一種情況樣式 ******************* */
  .bar-view{
		width:750rpx;
		position: fixed; 
		top:0;
		left:0;
		z-index:100;
		margin-bottom: 200px;
	}

/* 狀態欄樣式 */
	.statuColumn{
		width:100%;
		text-align: center; 
		background-color: green;
		color:#fff;
	}
	
	/* 標題欄樣式 */
	.titleColumn {
		display: flex;
		align-items: center;
		width: 100%;
		position: relative;
	}

	.titleColumn .titleColumn-title {
		position: absolute;
		left: 50%;
		font-size: 38upx;
		transform: translateX(-50%);
	}
	.titleColumn-back{
		position: absolute;
		left:15upx;
		font-size:30upx;
		padding: 10upx;
		border-radius: 50%;
	}

  /* ************** 第二種與第三種情況樣式  ********************* */
  .header {
		display: flex;
		align-items: center;
		top: 0;
		position: fixed;
		width: 100%;
		z-index: 100;
		left:0;
	}
	
	.header .header-title {
		position: absolute;
		left: 50%;
		font-size: 38upx;
		transform: translateX(-50%);
	}
	.header-back{
		position: absolute;
		left:15upx;
		font-size:30upx;
		padding: 10upx;
		border-radius: 50%;
	}

  

2、引用文件

index.wxml

<bar nav="{{setNav}}"></bar>
<view class="" style="height:3000rpx;background-color:pink;">
			正文
</view>

index.js

Page({
  data:{
    setNav: {
      bg: 'yellow',  //背景色
      color: 'red',  //字體顏色
      isdisPlayNavTitle: true, //是否顯示返回按鈕,由於導航欄是共用的,把所有的東西封裝好,
      // 然後有些頁面不需要的東西通過條件控制進行顯示與隱藏
      navTitle: '標題欄' //導航標題
    }
  }
})

五、第二與第三種情況結果展示

六、說明

     關於組件傳值可以看這裏:https://blog.csdn.net/Syleapn/article/details/97286960

此處不再說明~

   

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章