久不寫文,手有些生,見諒。
最近App專案要將其中一個模組抽出來做成小程式, 功能包含 :底部的Tab欄,頂部的標題欄
這裡選擇自定義的原因有兩點:
- narBar 微信原生不支援設定返回圖示,且在 Android 上標題是居左顯示,在 iOS 上是居中顯示。
- 底部的 tabBar 不支援點選跳頁面,圖示佈局不支援超過 tabBar 的高度。
下面兩張圖是簡單實現的效果。
以上效果我也是參考的網上例子來實現,可看該效果原作的分析。或者看看下面我的理解。
微信小程式自定義元件
文件中說明了自定義元件
- 可以將頁面內的功能模組抽象成自定義元件,以便在不同的頁面中重複使用。
- 也可以將複雜的頁面拆分成多個低耦合的模組,有助於程式碼維護。
建立自定義元件
在最新的開發工具中已經支援直接建立元件了,建立一個 components
目錄,然後在建立一個元件對於的目錄,例如這裡建立的是tabbar
目錄,然後在該目錄點選滑鼠右鍵選擇新建Component
,輸入元件名稱即可,例如這裡輸入的是tabbar
。
元件模板和樣式
類似於頁面,自定義元件擁有自己的wxml
模板和 wxss
樣式
在元件模板中可以提供一個<slot>
節點,用於承載元件引用時提供的子節點。這個<slot>
節點相當於元件佔位符。
預設情況wxml
中只支援一個<solt>
節點,可以設定支援多個<solt>
節點:
佈局編寫好之後就開始設定樣式了,在頁面中可以通過wxss
來定義,也可以通過設定元件的class
名稱,然後再呼叫該元件的 wxss
中定義樣式。
元件的wxss
預設是不支援app.wxss
樣式的,但是可以像設定多<slot>
一樣,進行設定:
模板資料繫結
通過呼叫 Component構造器時可以指定元件的屬性、資料、方法等。developers.weixin.qq.com/miniprogram…
Component({
// 詳細使用看文件
behaviors: [],
properties: {
myProperty: { // 屬性名
type: String, // 型別(必填),目前接受的型別包括:String, Number, Boolean, Object, Array, null(表示任意型別)
value: '', // 屬性初始值(可選),如果未指定則會根據型別選擇一個
observer(newVal, oldVal, changedPath) {
// 屬性被改變時執行的函式(可選),也可以寫成在methods段中定義的方法名字串, 如:'_propertyChange'
// 通常 newVal 就是新設定的資料, oldVal 是舊資料
}
},
myProperty2: String // 簡化的定義方式
},
data: {}, // 私有資料,可用於模板渲染
lifetimes: {
// 生命週期函式,可以為函式,或一個在methods段中定義的方法名
attached() { },
moved() { },
detached() { },
},
// 生命週期函式,可以為函式,或一個在methods段中定義的方法名
attached() { }, // 此處attached的宣告會被lifetimes欄位中的宣告覆蓋
ready() { },
pageLifetimes: {
// 元件所在頁面的生命週期函式
show() { },
hide() { },
resize() { },
},
methods: {
onMyButtonTap() {
this.setData({
// 更新屬性和資料的方法與更新頁面資料的方法類似
})
},
// 內部方法建議以下劃線開頭
_myPrivateMethod() {
// 這裡將 data.A[0].B 設為 'myPrivateData'
this.setData({
'A[0].B': 'myPrivateData'
})
},
_propertyChange(newVal, oldVal) {
}
}
})
複製程式碼
在上面的程式碼中我們可以通過properties
和setData
結合實現動態設定資料,在methods
中可以定義方法,用於給外部呼叫,也就是元件間的通訊。
元件間通訊
可以通過
triggerEvent
或者直接獲取元件this.selectComponent
示例來呼叫方法和屬性。
- triggerEvent
- 父元件還可以通過 this.selectComponent 方法獲取子元件例項物件,這樣就可以直接訪問元件的任意資料和方法。
開始使用元件
在頁面的json
檔案中配置元件的路徑,如下:
{
"usingComponents": {
"navbar": "/components/navbar/index",
"tabbar": "/components/tabbar/tabbar"
}
}
複製程式碼
在頁面的wxml
佈局中新增,如下:
// 引入元件
<navbar navbar-data='{{nvabarData}}'></navbar>
// 內容
<view class="home-page">
<view style='margin-top: {{height}}px;margin-bottom:10px;'></view>
</view>
// 引入元件
<tabbar tabbar="{{tabbar}}"></tabbar>
複製程式碼
自定義 tabBar 元件分析
看文章頂部原作者的分析。下面介紹一些坑。
-
雖然在元件的
js
檔案中已經設定了tabbar
但是在app.json
中還是需要配置tabbar
,詳細配置可看文章頂部github
連結。 -
在頁面的
onload
中還需要再設定一次
wx.hideTabBar({
})
複製程式碼
因為從分享頁面點選左上角的首頁圖示回到首頁會出現兩個tabbar
,所以在首頁還需要再隱藏一次tabbar.
- 注意路徑問題,新版的開發工具
components
檔案應該在miniprogram
下,和pages
為同級,否則在引入元件的路徑中可能會出錯。
自定義 navBar 元件分析
小程式中分享出去的頁面是沒有返回按鈕的,為了使用者能夠再次回到我們的小程式中,我們在 navbar 上自定義了一個返回按鈕和返回首頁的按鈕。
這裡通過小程式的場景值和使用一個全域性的變數share
來判斷是否是從分享頁面進來。在 app.js
中做了處理:
// 判斷是否由分享進入小程式
if (options.scene == 1007 || options.scene == 1008) {
this.globalData.share = true
} else {
this.globalData.share = false
};
複製程式碼
為了適配頂部的高度,在wxml
佈局中還動態設定了一個margin-top
的高度,這個高度通過獲取系統的狀態列高度得到。
getSystemInfo: function () {
let t = this;
wx.getSystemInfo({
success: function (res) {
// 獲取高度
t.globalData.height = res.statusBarHeight;
}
});
},
複製程式碼
然後在頁面的data
中設定元件的資料和狀態列的高度:
data: {
// 元件所需的引數
nvabarData: {
showCapsule: 0, //是否顯示左上角圖示 1表示顯示 0表示不顯示
title: '讓故事發生', //導航欄 中間的標題
},
// 此頁面 頁面內容距最頂部的距離
height: app.globalData.height * 2 + 20,
// tabbar
tabbar: {},
},
複製程式碼
原作者在實現圖示的顯示和隱藏部分邏輯和我的預期不一致,我想實現的是從分享頁面進入才顯示左上角的返回首頁圖示,正常也就只顯示返回按鈕。修改點後的wxml
如下:
<view bindtap='_navback' wx:if='{{!share}}'>
<image src='/images/back.png' mode='aspectFill' class='back-pre'></image>
</view>
// 這裡把 share 取反去掉
<view class='navbar-v-line' wx:if='{{share}}'></view>
// 這裡把 share 取反去掉
<view bindtap='_backhome' wx:if='{{share}}'>
<image src='/images/icon/icon_home.png' mode='aspectFill' class='back-home'></image>
</view>
複製程式碼
本文完~,喜歡就點個讚唄。