微信小程式個人心得
昨天看了一下微信小程式官方文件,總結一下自己學習的個人心得.
首先從官方文件給的框架說起,微信小程式官方文件給出了app.js, app.json, app.wxss.
先從這三個檔案說起.
- app.js 這個檔案是整個小程式的入口檔案,開發者的邏輯程式碼在這裡面實現,同時在這個資料夾裡面可以定義全域性變數.
- app.json 這個檔案可以對小程式進行全域性配置,決定頁面檔案的路徑,視窗表現,設定網路超時時間,設定多tab等.
- app.wxss 是小程式的公共樣式表.(為了適應廣大的前端開發者,我們的 WXSS 具有 CSS 大部分特性。 同時為了更適合開發微信小程式,我們對 CSS 進行了擴充以及修改。)
接著我們就結合官方給出的程式碼具體說一下上面提到的三個檔案.
- 首先說的是配置檔案app.json.下面是官方給出的例子.
{
"pages": [
"pages/index/index",
"pages/logs/index"
],
"window": {
"navigationBarTitleText": "Demo"
},
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首頁"
}, {
"pagePath ": "pages/logs/logs",
"text": "日誌"
}]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"debug": true
}
官方給出了app.json五個配置項列表.(pages(Array), window(Object), tabBar(Object), networkTimeout(Object), debug(Boolean)),接著我們就詳細的分下一下這幾個配置項.
pages
它的作用是配置小程式的頁面,這個配置項是必填的,它接受一個數組
"pages": [
"pages/index/index",
"pages/logs/index"
]
可以看出,每一項分別對應的都是實現檔案的路徑以及他的檔名.
注意:這個配置裡面的第一行配置是它的初始頁面,例如上面程式碼的初始頁面就是index
window
這個配置項是用來設定小程式的狀態列、導航條、標題、視窗背景色。
他給出了六個屬性(navigationBarBackgroundColor(HexColor), navigationBarTextStyle(String-(black,white)), navigationBarTitleText(String), backgroundColor(HexColor), backgroundTextStyle(String-(dark,light)), enablePullDownRefresh(Boolean)),開發者可以根據自己的需求來進行配置.
我們詳細說一下這幾個屬性分別的功能:
- navigationBarBackgroundColor 它是用來設定導航欄背景顏色,這個屬性要輸入的是十六進位制顏色值.
- navigationBarTextStyle 它是用來導航欄標題顏色的,它的輸入型別是字串(String),但是現在官網給出的文件目前僅支援(black和white)這兩種顏色.
- navigationBarTitleText 這個屬性是顯示導航欄標題內容的,開發者可以根據自己的需要來進行設定.
- backgroundColor 這個屬性是設定視窗的背景色的,它需要輸入的也是十六進位制顏色值的.
- backgroundTextStyle 這個屬性我的理解是設定視窗內容的樣式的,官方給出的標準說明是下拉背景字型、loading 圖的樣式,這個屬性同navigationBarTextStyle屬性一樣目前僅支援兩種顏色(dark和light).
- enablePullDownRefresh 這個屬性是設定是否開啟下拉重新整理,預設是開啟的,注意: 在這個配置檔案(app.json)中如果關閉了下拉重新整理,當你在你自己開發的頁面中想要設定下拉重新整理也是行不通的,也就是說如果你想要在以後頁面中使用下拉重新整理這個功能,就必須保證這個配置檔案中的這一項設定是開啟的.
上面給出的示例程式碼:
{
"window":{
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "微信介面功能演示",
"backgroundColor": "#eeeeee",
"backgroundTextStyle": "light"
}
}
顯示出來的效果是這樣的:
tabBar
這個配置項是用來配置頁面底部的tab欄的,開發者可以根據自己的需求來進行配置.
注意: tabBar是一個陣列,只能配置最少2個,最多5個,而且tab欄的順序是按照陣列的排序來的.
tabBar官方給出了一下五個屬性(color(HexColor), selectedColor(HexColor), backgroundColor(HexColor), borderStyle(String), list(Array) ).
接下來說說我對這五個屬性的理解:
- color 設定tab上的文字預設顏色
- selectedColor 設定tab上的文字選中的顏色
- backgroundColor 設定tab的背景顏色
borderStyle 設定邊框的顏色,現在僅支援(black和white)
上面這四個屬性就是按照官方給出的API來設定就可以,下面說一下list屬性.list屬性接受的是一個數組(Array),在list下面配置的每一項都是一個物件,他們都有以下這四個屬性(pagePath(String), text(String), iconPath( String), selectedIconPath(String)).
pagePath 這個定義的是頁面的路徑,但是這個屬性定義的路徑必須是在pages上定義過的.
text 設定的是按鈕上的文字
iconPath 是定義icon圖片的路徑,這個屬性定義的圖片大小不超過40kb
selectedIconPath 定義的是當選中按鈕之後顯示的圖片,同樣圖片的大小不能超過40kb.下面是官方給出的效果圖:
networkTimeout
它是用來設定各種網路請求的超時時間的,單位是毫秒,官方給出了四個屬性(request, connectSocket, uploadFile, downloadFile)這四個屬性分別定義的是wx.request, wx.connectSocket, wx.uploadFile, downloadFile 這四個API的超時時間.
debug
如果在app.json將debug配置為true,那麼在開發者工具的控制檯面板中可以輸出詳細的除錯資訊.
以上就是根據官方給出的文件,我學習之後對app.json配置一些心得,下面我們在看一下app.js 這個檔案.
可以看到app.js這個檔案的字尾是js,沒錯,微信小程式的開發框架在邏輯層用的語言就是JavaScript.但是微信小程式也在JavaScript的基礎上做了一個修改,可以稱之為一個新的輪子.這個框架可以使開發者更加方便的呼叫一些微信的功能,例如掃一掃,微信支付等一些微信特有的功能.
我們接著回到app.js這個檔案中來,其他的稍後再說.
這個檔案是整個小程式的入口檔案,也可以說是控制整個小程式生命週期的檔案,那麼我們就不難想象,我們在這個檔案中應該實現的幾個功能,首先我們肯定需要對整個程式進行註冊,正好微信給我們提供了一個app()來實現對整個程式的註冊,同時app()裡面還實現了對小程式生命週期的監控函式(onLaunch, onShow, onHide), 其中onLaunch是監聽小程式初始化,當初始化完成時會觸發onLaunch,當然這個函式是全域性只觸發一次.onShow是監聽小程式的顯示,在小程式啟動時候,或者當你從後臺進入到前臺的時候就會觸發這個函式.而onHide函式是監聽小程式的隱藏的,當你從前臺切換到後臺的時候,會觸發onHide.有了這些一個小程式的例項基本上算是完成了,當然為了讓開發者加入更多自己的邏輯,微信還提供了讓開發者在app()中加入自己的邏輯,開發者可以可以新增任意的函式或資料到 Object 引數中,用 this 可以訪問.
注意:app()只能定義在app.js中,而且不能註冊多個.
當在app.js中註冊了例項之後,如果你想在自己的邏輯頁面呼叫它,你可以用getApp()這個全域性函式,這樣你就可以全域性呼叫app()裡面的資料.
微信給出的官方程式碼如下:
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data
注意:getApp()獲取裡實例之後,不要私自呼叫生命週期函式. 而且不要在app.js中用getApp()函式,用this就可以呼叫app()裡面的東西.
基本上app.js就這些東西,還有一些API裡面的內容會在後面一一介紹.下面我們就看一下app.wxss這個檔案,一般來說做過網站開發的(我自己是用php來開發的,這是我個人的一點拙見,如有不對請見諒)相信對css寫在單獨的檔案中應該不會陌生,這個app.wxss也是類似的,不過他的的配置是針對全域性的,也就是說如果你在後面的page中沒有重新配置他,那麼他就會呼叫這個檔案中的樣式設定,但是如果你有個人需求,需要在每個頁面重新寫樣式,那也沒關係,他會自動覆蓋宰割檔案中的樣式.
當你重新建立一個微信小程式他就會出現這幾個檔案,以上是我結合官方文件對他們的一些理解,接下來就是page的邏輯,檢視,配置的一些心得.
page
這一塊就是開發者自己的業務實現檔案了. 每一個頁面可以放在一個資料夾中,這個資料夾中一般包括.js, .json, .wxml, .wxss 這四個檔案,微信官方還建議這四個檔案的名字最好和資料夾的名字一致.這個便於框架自動查詢,不需要做更多的配置.
當你開始做頁面的功能的時候這個時候在.js,也需要註冊,微信官方給出Page()這個函式來註冊一個頁面,他接受一個object引數,用其來指定頁面的初始資料,生命週期函式,事件處理函式.需要注意的是當你在註冊這個頁面的時候要確定在最開始的app.json這個配置檔案中已經配置過這個頁面,而且當你對程式有所改變的時候也要確保app.json這個檔案中的內容也隨之相應改動.
微信給Page()函式一下幾個屬性(data(Object), onLoad(function), onReady(Function), onShow(Function), onHide(Function), onUpload(Function), onPullDownRefresh(Function)),而且你也可以新增任意函式或者資料到object引數中,在這個頁面用this即可訪問.
下面就簡單的介紹一下這幾個官方給出的屬性:
- data - 實現頁面的初始化資料
- onLoad - 是生命週期函式,用來監聽頁面載入,一個頁面只會呼叫一次,它的引數可以獲取wx.navigateTo和wx.redirectTo及< navigator/>中的query.
- onReady - 同樣是生命週期函式,用來監聽頁面初次渲染完成,一個頁面只會呼叫一次,代表頁面已經準備妥當,可以和檢視層進行互動.對頁面的設定請在onReady之後設定,如wx.setNavigationBarTitle.
- onShow - 生命週期函式,用來監聽頁面顯示,每次頁面開啟都會呼叫一次.
- onHide - 生命週期函式,監聽頁面隱藏”,當wx.navigateTo或者底部tab切換之後呼叫.
- onUpload - 生命週期函式,用來監聽頁面解除安裝.當wx.navigateTo和 navigateBack的時候呼叫.
- onPullDownRefresh - 頁面相關事件處理函式,用來監聽使用者的下拉動作.但是需要在config的window選項中開啟enablePullDownRefresh,當資料重新整理完成之後,可以用wx.stopPullDownRefresh停止當前頁面的下拉重新整理.
下面是微信給出的官方程式碼:
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// Do some initialize when page load.
},
onReady: function() {
// Do something when page ready.
},
onShow: function() {
// Do something when page show.
},
onHide: function() {
// Do something when page hide.
},
onUnload: function() {
// Do something when page close.
},
onPullDownRefresh: function() {
// Do something when pull down
},
// Event handler.
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
})
}
})
上面說了用data屬性來設定頁面的初始化資料,但是如果我們想改變資料裡面的值,怎麼辦??
那麼我們就介紹一個微信官方給我們提供的setData()函式,這個函式可以將資料從邏輯層傳送到資料層,同時還可以改變this.data的值.
setData()接受一個物件引數,讓資料以key,value的形式表示將this.data中key對應的值改變成value.
下面是微信官方給出的page的生命週期的圖片:
在小程式中的所有頁面路由全部由框架進行管理,對於路由的觸發方式以及頁面的生命週期函式可以通過呼叫API來進行..
下面我們就簡單的介紹一下微信小程式的API.
微信小程式框架給我們提供了豐富的微信原生API,可以方便的呼叫微信提供的能力,如獲取使用者資訊,本地儲存,支付功能等.
下面是微信關於API提供的說明:
- wx.on 開頭的API是監聽某個事件發生的API介面,接受一個CALLBACK函式作為引數,當事件觸發時,會呼叫CALLBACK函式.
- 如未有特殊約定,其他API介面都接受一個object作為引數.
- OBJECT 可以指定success,fail,complete來接受介面呼叫結果.
API的具體呼叫請看 微信小程式API文件
因為現在微信小程式還在內測期間,我也沒有內測號,所以具體的呼叫API程式碼需要在微信小程式開放之後,根據具體的邏輯進行實現.而且微信API文件已經給的非常清楚,相信呼叫不會太過困難.
上面的這些就是微信小程式page的頁面註冊以及API功能實現,但是我們知道光有這些是不夠的,在網際網路發展到現在我們更加註重的是人機互動,讓使用者有一個更好的體驗才算是 一個好的程式,那麼接下來我們就講講微信小程式是如何對頁面進行渲染的。
在微信小程式中採用了微信自己原生的渲染方式。微信小程式的頁面佈局採用的是wxml,然後結合基礎元件,事件系統構建出來頁面的結構。
wxml中有資料繫結,條件渲染,列表渲染, 模版,事件, 引用這幾種方式,下面我們就具體說說這幾種方式。
資料繫結 在上面我們已經說過了在Page()註冊頁面的時候,裡面會有一個data屬性來定義初始化資料,現在頁面渲染的資料繫結的時候就需要呼叫data裡面的資料了。下面看一下官方給出的例子。
<view> {{ message }} </view>
Page({
data: {
message: 'Hello MINA!'
}
})
從上面的程式碼可以看出來在檢視層接受邏輯層的程式碼的時候需要用2個大括號把資料的鍵值包起來就可以得到資料的值。當然在檢視層還可以進行運算(三元運算,算術運算),邏輯判斷,字串運算,而且還可以在大括號裡面進行組合(陣列,物件(雖然可以隨意組合,但是如果後面的變數名和前面的變數名相同的話,那麼後面的會覆蓋前面的))。
條件渲染 顧名思義所謂的條件渲染,就是通過條件來判斷是否需要渲染該程式碼塊。條件渲染主要是用到wx:if 和 block wx:if 這兩個,第一個相信好理解,第二個是在block裡面進行條件渲染,這裡我們特別說明一下< block/>並不是一個元件,它僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性。和我們以前的邏輯程式設計類似,既然有了wx:if ,那麼我們也會有wx:elseif和wx.else,這幾個組合起來,可以使條件渲染更加靈活。
在這裡官方文件中提到了一個wx:if和hidden的對比,通過合理的運用這兩種方法可以使你的程式更優。下面我們就是說說他們倆的區別:
因為wx:if之中也可能包含資料繫結,所以當wx:if的條件值切換時,框架有一個區域性渲染的過程,他會確保條件在切換是銷燬或者重新渲染。同時wx:if也是有惰性的,如果初始渲染條件為false,框架什麼也不會做,只有在條件第一次變為真的時候才會開始渲染。相比之下hidden就簡單的多,元件始終都會被渲染,只是簡單的控制顯示和隱藏,一般來說,wx:if 有更高的切換消耗,而hidden有更高的初始渲染消耗,你可以根據自己的需求來呼叫。
列表渲染 – wx:for
下面我們就說說wx:for的用法,wx:for繫結一個數組,就可使用陣列中各項資料重複渲染該元件,注意預設陣列的當前項的下標變數名預設為index,陣列當前項的變數名為item,,當然你也可以根據自己的需要來重新定義這兩個名字,使用wx:for-item可以指定陣列當前元素的變數名,wx:for-index可以指定陣列當前下標的變數名,wx:for也可以巢狀,這個時候就需要改變預設框架給定義的名字了。
下面是官方給出的事例程式碼:
<view wx:for="{{items}}">
{{index}}: {{item.message}}
</view>
Page({
data: {
items: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
模版
WXML提供模版(template),可以在模版中定義程式碼片段,然後在不同的地方呼叫.微信小程式的模版可以用name來命名它的名字,在使用的時候用is來宣告使用的模版,然後將模版所需要的data傳入即可,下面我們用官方文件給的程式碼來看一下如何宣告及呼叫模版.
<!--
index: int
msg: string
time: string
-->
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
上面這段程式碼可以看到模版的名字是”msgItem”.
<template is="msgItem" data="{{...item}}"/>
在呼叫的時候使用方法如上,在is屬性加上模版的名字即可.後面還有一個data屬性,並且在裡面還加入資料,下面我們就看一下下面這段程式碼.
Page({
data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
}
})
也許有的人可能對data屬性裡面資料繫結的內容有點兒疑問,”{{…item}}”這種呼叫是可以將上面程式碼中的item物件展開,讓資料迴圈呼叫該模板.
當然如果模版的功能僅僅是這樣,那麼他的可用性就太差了,事實當然不會是這樣,模版也可以根據你自己的條件來判斷在那種情況下渲染那種模版,下面我們就看一下官方給出的程式碼.
<template name="odd">
<view> odd </view>
</template>
<template name="even">
<view> even </view>
</template>
<block wx:for="{{[1, 2, 3, 4, 5]}}">
<template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
</block>
通過上面對條件渲染的介紹,我們可以看到在迴圈掉陣列[1,2,3,4,5]之後item陣列屬性在三元運算中判斷呼叫哪一個模版.
在這兒再多說一句模版也有自己的作用域,只能使用data傳入的資料,當然data傳入的資料可以是你自己新建的資料,也可以是你在配置中寫好的初始化資料.
好了現在我們說完模版了,可能有的同學就該想了,我寫好模版之後該如何呼叫它,如果他們是在一個頁面那肯定沒問題,但是這樣的話可用性還是很差啊,如果我想把模版單獨放在一個頁面,在呼叫它的時候該怎麼辦啊?沒關係,微信小程式早就考慮到了,那麼我們接下來就說說引用.
引用
WXML提供兩種引用方式import和include.
接下來我們就先說說import這種方式,我們就結合程式碼來看,它呼叫在不同頁面的模版訊息如下:
<!-- item.wxml -->
<template name="item">
<text>{{text}}</text>
</template>
在 index.wxml 中引用了 item.wxml,就可以使用item模板:
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
這裡要注意一下,import引用也是有作用域這個概念存在的,它只會定義import目標檔案中定義的template,而不會import目標檔案import中的template.簡而言之就是import只能引用template而不能引用import.
上面說了import是如何引用的,那麼我們接著看一下include是怎麼引用的.
include引用和import唯一不同點就是他的引用相當於複製,他會複製< template>裡面的全部內容,但是不包含< template>,看一下程式碼相信你可以理解的更加明白.
<!-- index.wxml -->
<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>
<!-- header.wxml -->
<view> header </view>
<!-- footer.wxml -->
<view> footer </view>
上面我們說的檢視層這些方法已經可以構成一個靜態的頁面了,但我們現在是21世紀啊,一個沒有人機互動的程式怎麼能在這個世界生存下來了?在使用者體驗至上的今天,微信小程式不可能不考慮到這一點,接下來我們就說說檢視層的事件方法.
先來說說什麼是事件,相信有的人看到這兒肯定是一臉懵逼,你這說的啥玩意兒,說的這麼專業,我還不如看文件去.那麼我們就說說什麼是事件.
事件就是一種頁面到邏輯層的通訊方式,比如說你的操作想得到機器的反饋,這時候就用到事件了.事件可以將使用者的行為反饋到邏輯層進行處理.
說到這兒不禁又有一個問題,那他是怎麼用的呢? 事件可以繫結到元件上,當觸發事件,就會執行邏輯層對應的事件處理函式,當然為了更加方便人機互動,使用者還可以攜帶額外的資訊,如id,data等.
可能有人看完剛才的一段就說了,好了,你剛才說的事件解釋的差不多了,可是你為什麼有冒出一個元件,這讓我這麼理解?
既然說到元件了,我們就先簡單的瞭解一下,在之後的元件板塊再詳說,先保證大家能看懂什麼是事件就好了.
為什麼要有元件呢?元件是框架為了開發者進行快速的開發而設計的.
那什麼是元件呢? 元件是檢視層的基本組成單元,在微信小程式中元件自帶一些功能與微信風格的樣式,一個元件通常包括開始標籤和結束標籤,屬性是用來修飾這個元件,內容在兩個標籤之內.
<tagname property="value">
Content goes here ...
</tagename>
在這裡需要注意一點,元件和屬性都是小寫,並且以”-“進行連線.
簡單的介紹一下元件,那我們繼續說事件.
事件分為冒泡事件和非冒泡事件,冒泡事件是當一個元件上的事件被觸發後,該事件會向父節點傳遞,而非冒泡事件則不會.
現在微信小程式給出的冒泡事件僅僅有6個(touchstart,touchmove, touchcancel,touchend,tap, longtap),下圖是他們分別對應的觸發條件.
剩下的都屬於非冒泡事件.
接下來我們就說說事件怎麼用?
事件是通過事件繫結來實現的.它的寫法是以key,value的形式來寫的.key以bind 和catch 開頭,然後跟上事件的型別. value 是一個字串,需要在對應的page中定義同名的函式,不然當觸發事件的時候會報錯.(bind 事件繫結不會阻止冒泡事件向上冒泡,而catch 可以阻止冒泡事件向上冒泡).
說完了如何進行事件綁定了,我們再說說,當事件觸發是邏輯層的事件處理函式會收到什麼? 事件處理函式會收到一個事件物件. 那麼這個事件物件裡面都有什麼屬性呢?? 裡面的屬性有(type, timeStamp, target, currentTarget, touches, detail),下面是他們的一些說明:
- type得到的是通用事件型別,例如tap.
- timeStamp是頁面開啟到事件觸發所經過的毫秒數.
- target觸發事件的源元件,它包括事件源元件的id,data-開頭自定義屬性的組成的集合(dataset),以及他在座標系統中的偏移量.
- currentTarget 觸發事件的當前事件,它包括的內容與target相同.
其他的屬性按照上面的說明簡單瞭解即可,在這裡我們說一下target和currentTarget中的dataset,我們知道在元件中可以定義資料,這些資料會通過事件傳遞給 SERVICE書寫方式: 以data-開頭,多個單詞由連字元-連結,不能有大寫(大寫會自動轉成小寫)如data-element-type,最終在 event.target.dataset 中會將連字元轉成駝峰elementType。用一段程式碼來說話相信大家就更清楚了.
<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
Page({
bindViewTap:function(event){
event.target.dataset.alphaBeta == 1 // - 會轉為駝峰寫法
event.target.dataset.alphabeta == 2 // 大寫會轉為小寫
}
})
我不知道大家感覺怎麼樣,要是我自己剛開始看我寫的這一大段內容,我感覺我就該罵娘了,不是說麼NO圖NO BB,下面我就給大家上程式碼,相信看完之後事件這一塊基本上就明白了.
//檢視層的事件繫結
<view id="tapTest" data-hi="MINA" bindtap="tapName"> Click me! </view>
//邏輯層的事件處理函式
Page({
tapName: function(event) {
console.log(event)
}
})
//邏輯層的事件處理函式輸出的資訊
{
"type": "tap",
"timeStamp": 1252,
"target": {
"id": "tapTest",
"offsetLeft": 0,
"offsetTop": 0,
"dataset": {
"hi": "MINA"
}
},
"currentTarget": {
"id": "tapTest",
"offsetLeft": 0,
"offsetTop": 0,
"dataset": {
"hi": "MINA"
}
},
"touches": [{
"pageX": 30,
"pageY": 12,
"clientX": 30,
"clientY": 12,
"screenX": 112,
"screenY": 151
}],
"detail": {
"x": 30,
"y": 12
}
}
到這兒WXML的頁面結構就說完了,接著我們簡單說說WXSS就基本說完了.
在WXSS中引入了新的 尺寸單位rpx 它規定1rpx=0.5px = 1物理畫素
WXSS的樣式匯入使用@import語句可以匯入外聯樣式表,@import後跟需要匯入的外聯樣式表的相對路徑,用;表示語句結束.剩下的內容基本上和css相差不大,有興趣的可以看一下官方文件WXSS
元件
微信小程式會持續更新,請大家關注.