前言:
上一篇文章我們介紹了.wxml和.wxss文件,這篇文章對(duì)js文件進(jìn)行詳細(xì)的講解,首先貼上一個(gè)簡(jiǎn)單的js文件:
示例代碼:
//index.js
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.
},
onReachBottom:function(){
//?Do?something?when?page?reach?bottom.
},
onShareAppMessage:function(){
//?return?custom?share?data?when?user?share.
},
//?Event?handler.
viewTap:function(){
this.setData({
text:'Set?some?data?for?updating?view.'
})
},
customData:?{
hi:'MINA'
}
})
在之前解析的app.js文件中,里面又一個(gè)App()函數(shù) 而在每個(gè)界面的js文件中有一個(gè)Page()函數(shù)。
Page
Page()函數(shù)用來(lái)注冊(cè)一個(gè)頁(yè)面。接受一個(gè) object 參數(shù),其指定頁(yè)面的初始數(shù)據(jù)、生命周期函數(shù)、事件處理函數(shù)等。
object 參數(shù)說(shuō)明:
屬性類(lèi)型描述
dataObject頁(yè)面的初始數(shù)據(jù)
onLoadFunction生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載
onReadyFunction生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面初次渲染完成
onShowFunction生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面顯示
onHideFunction生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面隱藏
onUnloadFunction生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面卸載
onPullDownRefreshFunction頁(yè)面相關(guān)事件處理函數(shù)--監(jiān)聽(tīng)用戶(hù)下拉動(dòng)作
onReachBottomFunction頁(yè)面上拉觸底事件的處理函數(shù)
onShareAppMessageFunction用戶(hù)點(diǎn)擊右上角分享
其他Any開(kāi)發(fā)者可以添加任意的函數(shù)或數(shù)據(jù)到 object 參數(shù)中,在頁(yè)面的函數(shù)中用this可以訪(fǎng)問(wèn)
初始化數(shù)據(jù) data
初始化數(shù)據(jù)將作為頁(yè)面的第一次渲染。data 將會(huì)以 JSON 的形式由邏輯層傳至渲染層,所以其數(shù)據(jù)必須是可以轉(zhuǎn)成 JSON 的格式:字符串,數(shù)字,布爾值,對(duì)象,數(shù)組。
渲染層可以通過(guò)WXML對(duì)數(shù)據(jù)進(jìn)行綁定。
示例代碼: 使用雙大括號(hào)包裹起來(lái)
{{text}}{{array[0].msg}}
Page({
data:?{
//data里面的數(shù)據(jù)類(lèi)型只有這5中 最后一種object最常用 一般的json格式就是這樣的。 所以在獲取服務(wù)器數(shù)據(jù)的時(shí)候直接賦值給 object(但是記得定義哦。)
text:'init?data', //字符串
array:?[{msg:'1'},?{msg:'2'}],//數(shù)組
age:18, ?//數(shù)字
hidden: false, ?//布爾
object: {
name: 'yuanxiao',
names: [
{ id: 1, age: 2 },
{ id: 2, age: 12 }]
//對(duì)象 注意這里面包含 其他任何的類(lèi)型使用的時(shí)候只需要使用 {{ object.names }}
}
})
生命周期函數(shù)
onLoad: 頁(yè)面加載
一個(gè)頁(yè)面只會(huì)調(diào)用一次。
接收頁(yè)面參數(shù)可以獲取wx.navigateTo和wx.redirectTo及中的 query。
onShow: 頁(yè)面顯示
每次打開(kāi)頁(yè)面都會(huì)調(diào)用一次。
onReady: 頁(yè)面初次渲染完成
一個(gè)頁(yè)面只會(huì)調(diào)用一次,代表頁(yè)面已經(jīng)準(zhǔn)備妥當(dāng),可以和視圖層進(jìn)行交互。
對(duì)界面的設(shè)置如wx.setNavigationBarTitle請(qǐng)?jiān)趏nReady之后設(shè)置。詳見(jiàn)生命周期
onHide: 頁(yè)面隱藏
當(dāng)navigateTo或底部tab切換時(shí)調(diào)用。
onUnload: 頁(yè)面卸載
當(dāng)redirectTo或navigateBack的時(shí)候調(diào)用。
頁(yè)面相關(guān)事件處理函數(shù)
onPullDownRefresh: 下拉刷新
監(jiān)聽(tīng)用戶(hù)下拉刷新事件。
需要在config的window選項(xiàng)中開(kāi)啟enablePullDownRefresh。
當(dāng)處理完數(shù)據(jù)刷新后,wx.stopPullDownRefresh可以停止當(dāng)前頁(yè)面的下拉刷新。
onShareAppMessage: 用戶(hù)分享
只有定義了此事件處理函數(shù),右上角菜單才會(huì)顯示“分享”按鈕
用戶(hù)點(diǎn)擊分享按鈕的時(shí)候會(huì)調(diào)用
此事件需要 return 一個(gè) Object,用于自定義分享內(nèi)容
自定義分享字段
字段說(shuō)明默認(rèn)值
title分享標(biāo)題當(dāng)前小程序名稱(chēng)
path分享路徑當(dāng)前頁(yè)面 path ,必須是以 / 開(kāi)頭的完整路徑
示例代碼
Page({
onShareAppMessage:function(){
return{
title:'自定義分享標(biāo)題',
path:'/page/user?id=123'
}
}
})
事件處理函數(shù)
除了初始化數(shù)據(jù)和生命周期函數(shù),Page 中還可以定義一些特殊的函數(shù):事件處理函數(shù)。在渲染層可以在組件中加入事件綁定,當(dāng)達(dá)到觸發(fā)事件時(shí),就會(huì)執(zhí)行 Page 中定義的事件處理函數(shù)。
示例代碼:
click me
Page({
viewTap:function(){
console.log('view?tap')
}
})
Page.prototype.setData()
setData函數(shù)用于將數(shù)據(jù)從邏輯層發(fā)送到視圖層,同時(shí)改變對(duì)應(yīng)的this.data的值。
注意:
直接修改 this.data 無(wú)效,無(wú)法改變頁(yè)面的狀態(tài),還會(huì)造成數(shù)據(jù)不一致。
單次設(shè)置的數(shù)據(jù)不能超過(guò)1024kB,請(qǐng)盡量避免一次設(shè)置過(guò)多的數(shù)據(jù)。
setData() 參數(shù)格式
接受一個(gè)對(duì)象,以 key,value 的形式表示將 this.data 中的 key 對(duì)應(yīng)的值改變成 value。
其中 key 可以非常靈活,以數(shù)據(jù)路徑的形式給出,如array[2].message,a.b.c.d,并且不需要在 this.data 中預(yù)先定義。
示例代碼:
{{text}}Change normal data{{array[0].text}}Change Array data{{object.text}}Change Object data{{newField.text}}Add new data
//index.js
Page({
data:?{
text:'init?data',
array:?[{text:'init?data'}],
object:?{
text:'init?data'
}
},
changeText:function(){
//?this.data.text?=?'changed?data'? //?bad,?it?can?not?work
this.setData({
text:'changed?data'
})
},
changeItemInArray:function(){
//?you?can?use?this?way?to?modify?a?danamic?data?path
this.setData({
'array[0].text':'changed?data'
})
},
changeItemInObject:function(){
this.setData({
'object.text':'changed?data'
});
},
addNewField:function(){
this.setData({
'newField.text':'new?data'
})
}
})
最后還是提醒一個(gè)關(guān)于setData的細(xì)節(jié),一般的都是:this.setData({ ?text:"cyx" ?})
但是這里有個(gè)問(wèn)題就是this的作用域:
this的作用域在Page()函數(shù)內(nèi)部 可以來(lái)看看下面的這個(gè)demo:
wxml文件:
{{text}}
修改text信息
js文件:
bind:function(){
wx.getSystemInfo({
success: function(res) {
this.setData({
text:res.model
})
}
})
}
這個(gè)看起來(lái)其實(shí)是沒(méi)有問(wèn)題的,但是當(dāng)我們點(diǎn)擊這個(gè)button的時(shí)候,報(bào)錯(cuò)了:
但是為什么會(huì)說(shuō) this.setData沒(méi)有定義呢?
首先這是在wx.getSystemInfo內(nèi)部的回調(diào)方法 那么這個(gè)this就會(huì)代表這個(gè)回調(diào)方法,但是這個(gè)回掉方法中并沒(méi)有setData這個(gè)方法,
所以就出現(xiàn)了上面的方法未定義:
正確的寫(xiě)法是:
我們首先把this賦值給that,在wx.getSystemInfo內(nèi)部,我們使用that 那么就不會(huì)出現(xiàn)超出this的作用域范圍了。
頁(yè)面棧
框架以棧的形式維護(hù)了當(dāng)前的所有頁(yè)面。 當(dāng)發(fā)生路由切換的時(shí)候,頁(yè)面棧的表現(xiàn)如下:
路由方式頁(yè)面棧表現(xiàn)
初始化新頁(yè)面入棧
打開(kāi)新頁(yè)面新頁(yè)面入棧
頁(yè)面重定向當(dāng)前頁(yè)面出棧,新頁(yè)面入棧
頁(yè)面返回頁(yè)面不斷出棧,直到目標(biāo)返回頁(yè),新頁(yè)面入棧
Tab 切換頁(yè)面全部出棧,只留下新的 Tab 頁(yè)面
頁(yè)面的路由
在小程序中所有頁(yè)面的路由全部由框架進(jìn)行管理,對(duì)于路由的觸發(fā)方式以及頁(yè)面生命周期函數(shù)如下:
路由方式觸發(fā)時(shí)機(jī)路由后頁(yè)面路由前頁(yè)面
初始化小程序打開(kāi)的第一個(gè)頁(yè)面onLoad,onShow
打開(kāi)新頁(yè)面調(diào)用 APIwx.navigateTo或使用組件onLoad,onShowonHide
頁(yè)面重定向調(diào)用 APIwx.redirectTo或使用組件onLoad,onShowonUnload
頁(yè)面返回調(diào)用 APIwx.navigateBack或用戶(hù)按左上角返回按鈕onShowonUnload(多層頁(yè)面返回每個(gè)頁(yè)面都會(huì)按順序觸發(fā)onUnload)
Tab 切換調(diào)用 APIwx.switchTab或使用組件或用戶(hù)切換 Tab
各種情況請(qǐng)參考下表
Tab 切換對(duì)應(yīng)的生命周期(以 A、B 頁(yè)面為 Tabbar 頁(yè)面,C 是從 A 頁(yè)面打開(kāi)的頁(yè)面,D 頁(yè)面是從 C 頁(yè)面打開(kāi)的頁(yè)面為例):
當(dāng)前頁(yè)面路由后頁(yè)面觸發(fā)的生命周期(按順序)
A ? ? ? ? ? ? ? A ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Nothing happend
A ? ? ? ? ? ? ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? A.onHide(), B.onLoad(), B.onShow()
A ? ? ? ? ? ? ? ?B(再次打開(kāi)) ? ? ? ? ? ? ? A.onHide(), B.onShow()
C ? ? ? ? ? ? ? ? A ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? C.onUnload(), A.onShow()
C ? ? ? ? ? ? ? ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?C.onUnload(), B.onLoad(), B.onShow()
D ? ? ? ? ? ? ? ? ?B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?D.onUnload(), C.onUnload(), B.onLoad(), B.onShow()
D(從分享進(jìn)入)A ? ? ? ? ? ? ? ? ? ? ? ? ? ? D.onUnload(), A.onLoad(), A.onShow()
D(從分享進(jìn)入)B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?D.onUnload(), B.onLoad(), B.onShow()