小程序模板網(wǎng)

《微信小程序七日談》- 第四天:頁(yè)面路徑最多五層?導(dǎo)航可以這么玩 ...

發(fā)布時(shí)間:2018-04-08 10:48 所屬欄目:小程序開(kāi)發(fā)教程
本文作者:才子鍋鍋,來(lái)自授權(quán)地址,作者要求本文必須獲得作者親自授權(quán)同意方可轉(zhuǎn)載分享,如需轉(zhuǎn)載分享,請(qǐng)?jiān)谑跈?quán)地址內(nèi)征求原作者的同意;

微信小程序提供導(dǎo)航相關(guān)的API:

  • wx.navigateTo();
  • wx.redirectTo();
  • wx.navigateBack()。

使用wx.navigateTo()或者<navigator>組件跳轉(zhuǎn)的頁(yè)面路徑最多只有5層,這些頁(yè)面路徑是可以通過(guò)wx.navigateBack()API或者左上角返回按鈕按順序返回的。當(dāng)頁(yè)面路徑大于5層時(shí),使用wx.navigateTo()進(jìn)行下一頁(yè)嗎跳轉(zhuǎn)會(huì)拋出錯(cuò)誤:


navigateTo:fail webview count limit exceed.

但是某些業(yè)務(wù)場(chǎng)景存在多頁(yè)面互動(dòng)的交互邏輯,遠(yuǎn)遠(yuǎn)不止5層頁(yè)面棧。比如筆者近期參與開(kāi)發(fā)的58到家小程序中存在如下的業(yè)務(wù)場(chǎng)景:
1、用戶(hù)進(jìn)入小程序,展示首頁(yè);
2、首頁(yè)存在一個(gè)如下圖的底部導(dǎo)航欄:

用戶(hù)點(diǎn)擊“我的”進(jìn)入個(gè)人中心,此時(shí)頁(yè)面棧為首頁(yè)->個(gè)人中心,共2層。
3、個(gè)人中心頁(yè)面存在“我的收入”入口,如下:

4、用戶(hù)從個(gè)人中心進(jìn)入我的收入頁(yè)面,此時(shí)頁(yè)面棧為首頁(yè)->個(gè)人中心->我的收入,共3層;
5、我的收入頁(yè)面提供“提現(xiàn)”頁(yè)面的入口,如下:

6、用戶(hù)進(jìn)入提現(xiàn)頁(yè)面,此時(shí)的頁(yè)面棧為首頁(yè)->個(gè)人中心->我的收入->提現(xiàn),共4層。此時(shí)留給我們可支配的頁(yè)面棧只剩下一層了。提現(xiàn)流程如下:

提現(xiàn)流程存在多頁(yè)面直接的數(shù)據(jù)共享和交互,如果是常規(guī)的webapp,我們通常會(huì)考慮使用hash路由或者干脆做成獨(dú)立的幾個(gè)頁(yè)面使用url傳參進(jìn)行數(shù)據(jù)通信。但是進(jìn)入提現(xiàn)頁(yè)面之后,我們最多只能再添加一個(gè)獨(dú)立頁(yè)面了。也就是說(shuō),銀行列表頁(yè)、綁定銀行卡頁(yè)和提交成功頁(yè)三者只能再使用一個(gè)頁(yè)面棧(并非一個(gè)頁(yè)面)承載。如何用僅剩的最后一層頁(yè)面棧實(shí)現(xiàn)上述復(fù)雜的提現(xiàn)流程呢?

邏輯行為梳理

第一步:細(xì)分交互行為

首先第一步是將提現(xiàn)行為細(xì)分,因?yàn)橹荒茉偬砑右粋€(gè)獨(dú)立頁(yè)面,所以需要合并一些可在一個(gè)頁(yè)面完成的行為。上文的流程圖其實(shí)遺漏了一個(gè)行為:綁定銀行卡頁(yè)面點(diǎn)擊銀行卡需要顯示銀行列表頁(yè)。也就是允許用戶(hù)重新選擇銀行。所以其實(shí)整體的提現(xiàn)流程如下:

小程序標(biāo)題欄左上角返回按鈕的行為(圖中標(biāo)紅的線條)是返回頁(yè)面棧的上一頁(yè)面,代碼是無(wú)法干預(yù)的。

整個(gè)流程中必須支持“返回”按鈕正常返回上一頁(yè)面的行為有:

  • 前置頁(yè)面進(jìn)入提現(xiàn)頁(yè)面,正常返回前置頁(yè)面;
  • 提現(xiàn)頁(yè)面進(jìn)入的銀行列表頁(yè)面,正常返回提現(xiàn)頁(yè)面。

要保證第二條“提現(xiàn)頁(yè)面進(jìn)入的銀行列表頁(yè)面,正常返回提現(xiàn)頁(yè)面”,就必須將銀行列表頁(yè)獨(dú)立為一個(gè)頁(yè)面。至此,最后一層頁(yè)面棧就定型了。那么剩下的綁定銀行卡和提交成功頁(yè)面怎么辦呢?

第二步:合并邏輯頁(yè)面

需要注意的是,銀行列表頁(yè)面與綁定銀行卡頁(yè)面之間有一個(gè)雙向的交互行為,由于最后一個(gè)獨(dú)立頁(yè)面已經(jīng)確定為銀行列表頁(yè)了,所以不得不從中犧牲一定的用戶(hù)體驗(yàn):綁定銀行卡頁(yè)面跳轉(zhuǎn)到銀行列表頁(yè)后不能正常返回。有了這個(gè)前提,我們可以把銀行列表和綁定銀行卡兩個(gè)邏輯頁(yè)面合并為一個(gè)實(shí)體頁(yè)面,通過(guò)子路由控制行為展示。

再次回顧上文的交互流程圖還可以得到另外一個(gè)信息:提交成功頁(yè)面的返回邏輯與提現(xiàn)頁(yè)面完全相同。所以,兩者同樣可以合并為一個(gè)實(shí)體頁(yè)面,由子路由控制行為展示。

第三步:梳理行為邏輯

以第二步的合并規(guī)則為準(zhǔn),實(shí)體頁(yè)面的交互流程如下:

使用data.route實(shí)現(xiàn)子路由

微信小程序的Page是沒(méi)有子路由概念的,我們?cè)诖擞懻摰淖勇酚善鋵?shí)就是根據(jù)Page組件的某個(gè)data字段進(jìn)行不同模板的分發(fā)渲染。

首先定義支持的子路由列表:


// 路由列表
const ROUTES = {
  index: 'index',
  banklist: 'banklist',
  setcard: 'setcard',
  done: 'done'
};

我們?cè)诖a上又進(jìn)一步的融合,將第四層頁(yè)面和第五層頁(yè)面兩個(gè)實(shí)體頁(yè)面融合為同一個(gè)Page組件,通過(guò)子路由控制模板的渲染,之所以這樣做有以下幾點(diǎn)考慮:

  1. 兩個(gè)實(shí)體頁(yè)面之間有很多共用的數(shù)據(jù);
  2. 58到家的小程序是復(fù)用了現(xiàn)存的部分接口,兩個(gè)頁(yè)面之間的數(shù)據(jù)是混合在一起的,融合也是為了避免接口的重構(gòu);

既然融合為一個(gè)Page組件,那么如何實(shí)現(xiàn)頁(yè)面的跳轉(zhuǎn)呢?其實(shí)很簡(jiǎn)單,使用wx.navigateTo()API如下:


wx.navigateTo({
  url: './index?route=' + ROUTES.banklist
});

上述代碼實(shí)現(xiàn)了跳轉(zhuǎn)到同一Page組件的功能,并且跳轉(zhuǎn)的頁(yè)面會(huì)被加入到頁(yè)面棧中。

然后在index.wxml中增加路由數(shù)據(jù)的邏輯判斷分發(fā):


<block wx:if="{{route=='index'}}">
  <include src="_part/basic/index.wxml"/>
</block>
<block wx:if="{{route=='banklist'}}">
  <include src="_part/banklist/index.wxml"/>
</block>
<block wx:if="{{route=='setcard'}}">
  <include src="_part/setcard/index.wxml"/>
</block>
<block wx:if="{{route=='done'}}">
  <include src="_part/done/index.wxml"/>
</block>

前置頁(yè)面進(jìn)入第四層頁(yè)面時(shí)默認(rèn)的是index子路由頁(yè)面,有第五層頁(yè)面的綁定銀行卡提交后返回第四層頁(yè)面時(shí)顯示done子路由。這個(gè)邏輯中需要注意的是:

  • 第四層頁(yè)面跳轉(zhuǎn)第五層頁(yè)面是隱藏(Hide)而不是卸載(Unload);
  • 第五層頁(yè)面返回第四層頁(yè)面后會(huì)觸發(fā)第四層頁(yè)面的onShow鉤子函數(shù)。

也就是說(shuō),我們可以再onShow鉤子函數(shù)中進(jìn)行路由的分發(fā)。但是如何獲取路由字段呢?大家可能想到的第一個(gè)方案就是通過(guò)url傳參,可惜這個(gè)方案是行不通的。首先,微信小程序官方文檔中關(guān)于Page組件鉤子函數(shù)的說(shuō)明,只有onLoad函數(shù)可以獲取由url query傳遞的數(shù)據(jù),其余的任何鉤子函數(shù)都不能獲??;其次,第五層頁(yè)面的提交行為返回第四層頁(yè)面是由wx.navigateBack()API實(shí)現(xiàn)的,這個(gè)API的功能是返回頁(yè)面棧中的上一層頁(yè)面,并不支持指定的修改url,所以u(píng)rl傳參這條路是走不通的。

那么使用cookie是否可行呢?雖然微信小程序不支持cookie,但cookie的理念可以提供給我們解決問(wèn)題的思路:將數(shù)據(jù)先儲(chǔ)存在本地,跳轉(zhuǎn)頁(yè)面后獲取本地?cái)?shù)據(jù)進(jìn)行相應(yīng)處理。

有了思路,自然而然地便想到類(lèi)似cookie的本地storage。

使用storage進(jìn)行頁(yè)面間的數(shù)據(jù)通信

第一步:點(diǎn)擊第五層頁(yè)面的提交按鈕后,首先在storage中儲(chǔ)存第四層頁(yè)面的route值:


wx.setStorage({
    key: 'dj_deposits_route',
    data: ROUTES.done
});

第二步:在第四層頁(yè)面的onShow函數(shù)內(nèi)獲取storage中的route數(shù)據(jù)并賦值給data中的route字段,模板便會(huì)同步刷新:


let _route = wx.getStorageSync('dj_deposits_route');
this.setData({
    route: _route
});

總結(jié)

微信小程序的頁(yè)面路徑限制為最多5層,多于5層的頁(yè)面將不會(huì)跳轉(zhuǎn)并且會(huì)拋出錯(cuò)誤信息。而我們產(chǎn)品的某些業(yè)務(wù)場(chǎng)景不止存在5層的頁(yè)面路徑,在這種情況下,我們不得不犧牲一定的用戶(hù)體驗(yàn),以保證功能的完整。本文提到的方案是與業(yè)務(wù)場(chǎng)景息息相關(guān)的,只是一家之言,并非最佳實(shí)踐。希望能夠給大家一點(diǎn)參考。



易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開(kāi)源 碼云倉(cāng)庫(kù):starfork
本文地址:http://22321a.com/wxmini/doc/course/23132.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢(xún):800182392 點(diǎn)擊咨詢(xún)
QQ在線咨詢(xún)