一般情況下大多數(shù)頁(yè)面在加載時(shí)都需要進(jìn)行一些網(wǎng)絡(luò)檢查归薛、基礎(chǔ)配置數(shù)據(jù)的加載,而如果每個(gè)頁(yè)面都寫一遍顯然是特別愚蠢的做法,同樣是一件特別苦惱的事情主籍。
所以习贫,懶人自有懶辦法,提取通用 page init component千元,組合達(dá)到當(dāng)前小程序想要實(shí)現(xiàn)的效果苫昌。
Ta 里面有什么?
- 頁(yè)面初始化時(shí)的網(wǎng)絡(luò)監(jiān)察
- 頁(yè)面初始化時(shí)的必要數(shù)據(jù)加載
- 頁(yè)面初始化時(shí)的 Loading 交互
- 頁(yè)面初始化失敗時(shí)的提醒
實(shí)現(xiàn)結(jié)果
實(shí)現(xiàn)
在嘗試實(shí)現(xiàn)前幸海,先將實(shí)現(xiàn)步驟梳理和歸納一下祟身,找到其中的規(guī)律便于在接下來開發(fā)中編碼并且對(duì)于維護(hù)也能順理成章。
- 一個(gè) Loading 界面
- 一個(gè)能夠接收入?yún)⒌腻e(cuò)誤提醒界面
- 實(shí)現(xiàn)網(wǎng)絡(luò)檢查函數(shù)
- 核心配置數(shù)據(jù)請(qǐng)求
- 回調(diào)通知父級(jí)函數(shù)
達(dá)到以上條件物独,基本上就成功了一半袜硫,初始已具有一定模型。
component 的實(shí)現(xiàn)
init.wxml 基礎(chǔ)結(jié)構(gòu)
<view>
<view wx:if="{{!loading && !errStatus}}">
<slot name="page"></slot>
</view>
<view class="{{ (loading || errStatus) ? 'show':'' }}">
<view>
<!-- Loading -->
<view wx:if="{{loading}}"><text>Loading</text></view>
<!-- Error -->
<view wx:if="{{errStatus}}">
<view>
<view>{{errTitle}}</view>
<view>{{errContent}}</view>
</view>
<view>
<button>再次嘗試</button>
<button>回到主頁(yè)</button>
<button>聯(lián)系客服</button>
</view>
</view>
</view>
</view>
</view>
以上的代碼邏輯很簡(jiǎn)單
1.loading
與 errStatus
均為 false
時(shí)挡篓,顯示插槽內(nèi)的內(nèi)容婉陷, slot page
插槽,就是實(shí)際 init 完成后需要顯示的內(nèi)容
-
loading
或errStatus
任意為true
時(shí)顯示提示官研,提示 Loading 狀態(tài)或異常狀態(tài) -
errTitle
&errContent
則是異常時(shí)提示的內(nèi)容
init.js
Component({
options: {
addGlobalClass: true,
multipleSlots: true
},
properties: {
resyncUser: {
type: Boolean,
value: false
},
loopInit: {
type: Boolean,
value: false
},
autoHide: {
type: Boolean,
value: true
}
},
data: {
loading: true,
errStatus: false,
errTitle: '數(shù)據(jù)異常',
errContent: '可能發(fā)生了未知錯(cuò)誤秽澳,請(qǐng)重試',
},
pageLifetimes: {
show: function() {
if (!this._showLoop || this.data.loopInit) {
this.init().then(
() => {
this._showLoop = true
}
)
}
}
},
observers: {
'loading': function (loading) {
if (loading) {
this.setData({
errStatus: false
})
}
},
'errStatus': function (errStatus) {
if (errStatus) {
this.setData({
loading: false
})
}
}
},
methods: {
init: function(){
return new Promise((resolve, reject) => {
this.showLoading()
this.network()
.then(
() => {
return this.user()
}
)
.then(
user => {
if (this.data.autoHide){
this.hide()
}
this.triggerEvent('callback', {
user: user,
userJSON: user.toJSON()
})
resolve()
}
)
.catch(
err => {
reject()
}
)
})
},
user: function() {
return new Promise((resolve, reject) => {
getApp().user.get(this.data.sync).then(
user => {
resolve(user)
},
err => {
this.showError('賬戶異常', '同步賬戶時(shí)出現(xiàn)異常,請(qǐng)重新嘗試')
reject(err)
}
)
})
},
network: function() {
return new Promise((resolve, reject) => {
wx.getNetworkType({
success: res => {
if (res.networkType != 'none') {
resolve(true)
} else {
this.showError('網(wǎng)絡(luò)異常', '請(qǐng)檢查您的網(wǎng)絡(luò)連接')
reject(false)
}
},
})
})
},
hide: function(){
this.setData({
loading: false,
errStatus: false
})
},
showLoading: function() {
this.setData({
loading: true
})
},
showError: function(_title, _content) {
this.setData({
errStatus: true,
errTitle: _title,
errContent: _content
})
}
}
})
在 properties
中定義組件的對(duì)外屬性阀参,便于父級(jí)頁(yè)面在引用時(shí)進(jìn)行配置肝集,在我自己小程序中,同步用戶數(shù)據(jù)是我的核心配置函數(shù)蛛壳,我需要在所有頁(yè)都同步用戶數(shù)據(jù)且配置不相同杏瞻,所有有此定義,具體細(xì)節(jié)不表了衙荐。
-
resyncUser
:true
捞挥,強(qiáng)制同步;false
忧吟,引用變量緩存 -
loopInit
:表示是否需要循環(huán)初始化砌函,在component
無法監(jiān)聽 父級(jí)的onLoad
事件,所以父級(jí)每次onShow
時(shí)都會(huì)被初始化溜族,該參數(shù)則決定是否要將其阻斷讹俊。ture
,每次onShow
都初始化煌抒;false
仍劈,僅初始化一次 -
autoHide
表示初始化完成后是否要自動(dòng)隱藏 init。true
寡壮,初始化完成后自動(dòng)隱藏贩疙;false
讹弯,初始化后的隱藏決定權(quán)交給父級(jí)
.json 配置組件
"usingComponents": {
"INIT": "/pages/_copts/init/main"
}
.wxml 中的使用
<INIT id="init"
loopInit="{{false}}" autoHide="{{false}}"
bind:callback="init">
<view slot="page">
<!-- 你的代碼 -->
</view>
</INIT>
在具體使用該 init 的父級(jí)頁(yè)中配置 json 和引用 init 組件并對(duì)其 loopInit
autoHide
callback
進(jìn)行配置。
如果想直接使用这溅,也可以不用配置交給默認(rèn)值決定组民。
額外事項(xiàng)
在組件的 init.js
中我們定義多個(gè)方法,可以使用在父級(jí)節(jié)點(diǎn)使用 this.selectComponent
獲取組件示例后調(diào)用
this.selectComponent('#init').hide()
-
this.selectComponent('#init').showError('title','content')
這里不太推薦直接訪問和修改組件的屬性悲靴,我們僅提供方法調(diào)用臭胜,交給組件自身去修改屬性避免錯(cuò)亂。
番外
其實(shí)對(duì)于初始化的辦法很多種对竣,我這里是的辦法是根據(jù)自身的小程序特性和需要而確定庇楞,具體的源碼估計(jì)對(duì)看官意義也不甚大,我就不獻(xiàn)丑了否纬。文章的意義更多的還是拋磚引玉與記錄自身在寫代碼過程中的感想體悟吕晌。如果你有想法或打臉請(qǐng)隨時(shí)留言。
以上临燃,
玩的開心睛驳!