頁面特效 UI組件庫 菜單導航 窗口特效 幻燈片滑動 圖像相冊 表單 選項卡 表格 評分星級 手風琴 文本鏈接 布局 日歷 顏色選擇器 按鈕 圖表 html5 提示 ExtJS 在線客服 其他特效 地圖 樹形控件 移動開發 BootStrap 滑動條 文件上傳 表單驗證 分頁 播放器 Angular VUE

淺談下微信小程序中的路由(頁面跳轉、返回、刷新、頁面棧)

頁面特效 技術03-千編萬碼 1月前  次瀏覽

什么是小程序里的“路由”?路由器嗎?蒙蔽?好吧,在WEB應用中它其實就是分組數據包從源到目的地時,決定端到端路徑的網絡范圍的進程;在小程序里就是設置頁面的跳轉,返回,自動刷新等一些功能。

而在微信小程序里,“路由”有很多限制,所以我們在開發小程序的時候,需要深入了解,否則就會掉坑里,被人笑話。微信小程序官方文檔里提供了5種:wx.redirectTo(Object object)、wx.reLaunch(Object object)、wx.navigateTo(Object object)、wx.switchTab(Object object)、wx.navigateBack(Object object)。接下來逐個分析下。

wx.redirectTo(Object object)

關閉當前頁面,跳轉到應用內的某個頁面,但是不允許跳轉到 tabbar 頁面。

參數

Object object

屬性 類型 默認值 是否必填 說明 支持版本
url string
需要跳轉的應用內非 tabBar 的頁面的路徑, 路徑后可以帶參數。參數與路徑之間使用 ? 分隔,參數鍵與參數值用 = 相連,不同參數用 & 分隔;如 'path?key=value&key2=value2'
success function
接口調用成功的回調函數
fail function
接口調用失敗的回調函數
complete function
接口調用結束的回調函數(調用成功、失敗都會執行)

說明:這里一定要注意,在使用redirectTo()的時候,不能跳轉到底部導航的頁面;如果一個頁面用了它來跳轉,返回后不可逆,因為跳轉后直接被關閉,一般用在多個頁面的跳轉,然后從三級頁面,返回到首頁【跳級返回】。

不懂?來看個例子。

比如我最近做的一個答題項目需求:首頁》答題》成功。這個流程其實是可以可逆的,但是我們要求,答題成功后,返回后,直接到首頁,而不是答題頁面,那么在答題頁面跳轉到成功頁面就要用到redirectTo?;镜腏S寫法:

						
						
						
  1. wx.redirectTo({
  2. //目的頁面地址
  3. url: 'pages/index/index',
  4. success: function(res){
  5. },
  6. ...
  7. })

wx.reLaunch(Object object)

關閉所有頁面,打開到應用內的某個頁面。

參數

Object object

屬性 類型 默認值 是否必填 說明 支持版本
url string
需要跳轉的應用內頁面路徑 , 路徑后可以帶參數。參數與路徑之間使用?分隔,參數鍵與參數值用=相連,不同參數用&分隔;如 'path?key=value&key2=value2',如果跳轉的頁面路徑是 tabBar 頁面則不能帶參數
success function
接口調用成功的回調函數
fail function
接口調用失敗的回調函數
complete function
接口調用結束的回調函數(調用成功、失敗都會執行)

wx.reLaunch(),用的不是很多,他有一些版本的兼容(支持版本 >= 1.1.0),剛開始接觸這個方法的時候,也試了下,點擊“獲取用戶信息”按鈕后跳轉到首頁,刷新首頁的數據信息;我也看了網上的一些項目,也有些人類似的做法,你覺得好嗎?個人覺得,關閉所有頁面,重新打開跳轉,不是那么明智,如果是單純的想是刷新實時數據,可以用其他的方法,比如在onShow()里使用this.onload()等。當然啦,我們不能說它沒用,不然開發出來干啥呢,根據需求來決定吧。下面分享下之前做過的一個項目對于wx.reLaunch()的應用,直接上代碼:

												
												
												
  1. wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo">獲取授權信息

getUserInfo:function(e){ 
console.log('點擊加載+'+e) 
 app.globalData.userInfo = e.detail.userInfo 
let timer = setTimeout(function () { 
wx.reLaunch({  
 url: '/pages/index/index', 
fail: function () {  
 Tools.showModal("支付界面  reLaunch調用失敗,請重試"); 
wx.redirectTo({  
 url: '/pages/index/index', })  
 } 
 }); 
  
 }, 500)  
  
 this.setData({ 
 userInfo: e.detail.userInfo, 
 hasUserInfo: true  
 }) 
} 


說明:點擊獲取用戶信息,然后跳轉到首頁,大家可以參考下。這里要提醒下的是,從上面的代碼可以發現我們用了一個定時器(建議使用),也就是跳轉到首頁需要0.5S的延時,這個是針對頁面的一個加載緩存需要時間,比如調用接口的數據等,當然你可以使用loading預加載。

wx.navigateTo(Object object)

保留當前頁面,跳轉到應用內的某個頁面,但是不能跳到 tabbar 頁面。使用 wx.navigateBack 可以返回到原頁面。

參數

Object object
屬性 類型 默認值 是否必填 說明 支持版本
url string
需要跳轉的應用內非 tabBar 的頁面的路徑, 路徑后可以帶參數。參數與路徑之間使用 ? 分隔,參數鍵與參數值用 = 相連,不同參數用 & 分隔;如 'path?key=value&key2=value2'
success function
接口調用成功的回調函數
fail function
接口調用失敗的回調函數
complete function
接口調用結束的回調函數(調用成功、失敗都會執行)

wx.navigateTo()用得最多的,可逆轉,使用wx.navigateTo接口跳轉,原頁面保留,這個是跟redirectTo()最大的區別,也就是返回的話,需要一層層的返回,不能跳級返回。具體的用法:

wx.navigateTo({ 
 //目的頁面地址 
 url: 'pages/logs/index', 
 success: function(res){}, 
 ... 
} 

TIPS:跟頁面中的A鏈接差不多。

wx.switchTab(Object object)

跳轉到 tabBar 頁面,并關閉其他所有非 tabBar 頁面。

參數

Object object

屬性 類型 默認值 是否必填 說明 支持版本
url string
需要跳轉的 tabBar 頁面的路徑(需在 app.json 的 tabBar 字段定義的頁面),路徑后不能帶參數。
success function
接口調用成功的回調函數
fail function
接口調用失敗的回調函數
complete function
接口調用結束的回調函數(調用成功、失敗都會執行)

說明:跳轉到tabBar帶參數會掉坑里,需要特殊處理下。拿個網上案例來說明下:

																						
																						
																								
  1. toCategory:function(event){
  2. var cate_id = event.currentTarget.dataset.cate_id;
  3. wx.switchTab({
  4. url: '../category/category?cate_id='+cate_id,
  5. });
  6. },

比如,上面一段正常的傳參的代碼,按照上面寫的在category.js里得不到數據的;

																						
																						
																								
  1. onLoad:function(options){
  2. console.log(options);
  3. }

所以我們需要按照官方文檔,換一種思路來處理。

跳轉的時候在全局變量里設置一個變量cate_id,調到category.js中后.調取全局變量里的cate_id,用完后,再把扎個變量清除掉.具體實施如下:

																					
																					
																							
  1. toCategory:function(event){
  2. var cate_id = event.currentTarget.dataset.cate_id;
  3. app.globalData.cate_id=cate_id;//設置全局變量(app已經定義 var app=getApp())
  4. wx.switchTab({
  5. url: '../category/category'
  6. });
  7. },

分類頁category.js中寫上這一段:

																					
																					
																							
  1. onLoad:function(options){
  2. var that = this
  3. var cate_id=app.globalData.cate_id
  4. wx.request({
  5. url: app.globalData.httpsurl +'public/index.php?s=product/index',
  6. data:{
  7. cate_id:cate_id,
  8. },
  9. success:function(res){
  10. //清除全局變量cate_id
  11. app.globalData.cate_id=""
  12. that.setData({
  13. alldata:res.data,
  14. })
  15. }
  16. })
  17. },

就可以了。

wx.navigateBack(Object object)

關閉當前頁面,返回上一頁面或多級頁面??赏ㄟ^getCurrentPages() 獲取當前的頁面棧,決定需要返回幾層。

參數

Object object

屬性 類型 默認值 是否必填 說明 支持版本
delta number
返回的頁面數,如果 delta 大于現有頁面數,則返回到首頁。
success function
接口調用成功的回調函數
fail function
接口調用失敗的回調函數
complete function
接口調用結束的回調函數(調用成功、失敗都會執行)

注意:調用navigateTo跳轉時,調用該方法的頁面會被加入堆棧,而redirectTo方法則不會。見下方示例代碼:

																												
																												
																														
  1. // 此處是A頁面
  2. wx.navigateTo({
  3. url: 'B?id=1'
  4. })
  5. // 此處是B頁面
  6. wx.navigateTo({
  7. url: 'C?id=1'
  8. })
  9. // 在C頁面內 navigateBack,將返回A頁面
  10. wx.navigateBack({
  11. delta: 2
  12. })

navigateBack()也是可以攜帶參數返回的,我們可以自定義,如何實現呢,看下代碼:

																											
																											
																													
  1. let pages = getCurrentPages();//當前頁面
  2. let prevPage = pages[pages.length-2];//上一頁面
  3. prevPage.setData({//直接給上移頁面賦值
  4. item: e.currentTarget.dataset.item,
  5. selAddress:'yes'
  6. });
  7. wx.navigateBack({//返回
  8. delta:1
  9. })

回到上一頁,在data里定義item,selAddress,然后在onshow里:

																												
																												
																														
  1. let pages = getCurrentPages();
  2. let currPage = pages[pages.length-1];
  3. if (currPage.data.selAddress==""){
  4. that.getUserAddress(that.data.userId);
  5. }else{
  6. that.setData({//將攜帶的參數賦值
  7. address: currPage.data.item
  8. });
  9. }

這只是一個很簡單的案例,進一步的知識還要考大家去鉆研了。

頁面棧

大家可能對上面的一段代碼提出疑問,delta是什么東東?OK,這個就相關到另外一個知識點:頁面棧。

什么是頁面棧呢,簡單的說就是頁面的層級數,大家都知道,微信小程序最多訪問5層,也就是頁面棧最多是5。

小程序提供了getCurrentPages()函數獲取頁面棧,第一個元素為首頁,最后一個元素為當前頁面。在上面的代碼中,有提到過,比如delta:1。

使用wx.navigateTo每新開一個頁面,頁面棧大小加1,直到頁面棧大小為5為止;如果返回頁面棧會減1,當然這個只是正常邏輯,有特殊情況?往下看吧。

1、假如使用wx.navigateTo從四級頁面跳轉到二級頁面,此時會在頁面棧頂添加一個與二級頁面初始狀態一樣的界面,但兩個頁面狀態是獨立的。頁面棧大小會加1,如果頁面棧大小為5,則wx.navigateTo無效。

2、假如使用wx.redirectTo從四級頁面重定向到二級頁面,此時會將關閉四級頁面,并使用二級頁面替換四級頁面,但兩個頁面狀態是獨立的。此時的頁面棧大小不變,請注意和使用wx.navigateTo的區別。

3、假如當前頁面為五級頁面,使用wx.navigateBack:

  • 當delta為1,關閉五級頁面,當前頁面為四級頁面,頁面棧大小減1;

  • 當delta為2,關閉依次五級頁面和四級頁面,當前頁面為三級頁面,頁面棧大小減2;

  • 以此類推,直到棧底為止,也就是首頁。

看上去是不是很蒙蔽,不要緊,這個需要慢慢去了解,建議大家自己做個DEMO,然后每次返回或者進入下一頁,打印下頁面棧,您就會熟悉了。

總結

小程序應用越來越廣,我們需要不斷的拓展自己的技術面,才能迎合公司業務的發展速度,否則你會被淘汰。

OK,今天分享的內容有點多,初次了解的童鞋可以多花點心思去研究下,我最近做了一些小程序的項目,如果您不懂的可以咨詢,不吝賜教咯,然后可以加入我們的QQ群,或者關注我們的微信公眾號。

溫馨提示:上述內容難免有疏漏之處,如有大神路過,請多賜教。

相關鏈接

發表評論

2017怎样手机上赚钱