首頁 >微信小程式 >小程式開發 >微信小程式開發頁面攔截器的詳解

微信小程式開發頁面攔截器的詳解

黄舟
黄舟原創
2018-05-29 09:51:543928瀏覽

這篇文章主要介紹了微信小程式之頁攔截器的範例程式碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

場景

  • #小程式有52個頁面,其中13個頁面無需任何身份,另外39個頁面需要係統角色。對於這39個頁面,如果微信使用者沒有系統角色,則跳到登入頁。

  • 是否有系統角色資訊需要透過非同步請求來取得。

需求分析&實作

對需求進行抽象,其實要的就是一個過濾器,對小程式頁面的訪問進行過濾,符合條件的通過,不符合條件進行其他處理。

使用過php的laravel框架的童鞋,肯定一下子就聯想到了laravel框架的http中間件:

HTTP 中間件提供一個方便的機制來過濾進入應用程序的HTTP 請求,例如,Laravel 預設包含了一個中間件來檢驗用戶身份驗證,如果用戶沒有經過身份驗證,中間件會將用戶導向登錄頁面,然而,如果用戶通過身份驗證,中間件將會允許這個請求進一步繼續前進。當然,除了身份驗證之外,中間件也可以被用來執行各式各樣的任務,CORS 中間件負責替所有即將離開程序的響應加入適當的響應頭,一個日誌中間件可以記錄所有傳入應用程序的請求。

令人憂桑的是,微信小程式並沒有提供針對Page實例的中間件機制。所以只能從Page實例的生命週期下手。

對於onLoad,一個頁面只會呼叫一次;對於onShow,每次開啟頁面(例如小程式從後台轉到前台)都會呼叫一次。

在onLoad或onShow鉤子函數裡,對使用者身分進行校驗,透過後則拉取該頁面所需的數據,否則跳到登入頁。

//orderDetail.js
onShow: function () {
  let that = this;
  //身份校验
  service.identityCheck(() => {
     //跳转到登录页
     wx.redirectTo({
      url: "/pages/common/login/login"
     });
    }, () => {  
     //获取页面数据等等   
     that.getDetail(this.orderId);
     ...
    }
  );
 },

不過,每個頁面都要這樣寫,重複程式碼好多啊,侵入性也強。不如用裝飾函數(高大上的說法是裝飾者模式)來包裝一下:

//filter.js
function identityFilter(pageObj){
  if(pageObj.onShow){
    let _onShow = pageObj.onShow;
    pageObj.onShow = function(){
      service.identityCheck(()=>{
        //跳转到登录页
        wx.redirectTo({
          url: "/pages/common/login/login"
        });
      },()=>{
        //获取页面实例,防止this劫持
        let currentInstance = getPageInstance();
        _onShow.call(currentInstance);
      });
    }
  }
  return pageObj;
}

function getPageInstance(){
  var pages = getCurrentPages();
  return pages[pages.length - 1];
}

exports.identityFilter = identityFilter;

filter.js用以提供過濾器方法,除了現有的用戶身份攔截,後續如果需要其他攔截,可以在這個檔案增加。然後,在需要使用者身分攔截的小程式頁面程式碼裡,用filter.identityFilter處理一下就可以了:

//orderDetail.js
let filter = require('filter.js');
Page(filter.identityFilter({
  ...
  onShow: function () {
    //获取页面数据等等
    this.getDetail(this.orderId);
    //...
  },
  ...
}));

使用Promise進行最佳化

#上面的實作中,每次造訪頁面,都會執行一次取得使用者身分的方法(就是上面程式碼裡的service. identityCheck )。其實沒有必要,在小程式啟動的時候取得一次就行了。也就是說,放在app.js的onLaunch方法裡執行。

每個小程式頁面實例化時,一般也會執行非同步方法,用來取得頁面所需的資料。關鍵在於,我們需要保證,頁面的非同步方法 必須在 取得使用者身分的非同步請求 之後執行。

毋容置疑,Promise最擅長處理非同步請求的執行順序了。主子,快放程式碼粗來:

//app.js
App({
  onLaunch:function(){
    let p = new Promise(function(resolve,reject){
      service.identityCheck(resolve,reject);
    });
    this.globalData.promise = p; 
  },
  ...
  globalData: {
    promise:null,
  }  
});
//filter.js
const appData = getApp().globalData;
function identityFilter(pageObj){
  if(pageObj.onShow){
    let _onShow = pageObj.onShow;
    pageObj.onShow = function(){
      //改动点
      appData.promise.then(()=>{
        //跳转到登录页
        wx.redirectTo({
          url: "/pages/common/login/login"
        });
      },()=>{
        //获取页面实例,防止this劫持
        let currentInstance = getPageInstance();
        _onShow.call(currentInstance);
      });
    }
  }
  return pageObj;
}

小結

基本上實作了小程式頁面的使用者身分攔截器,但是比起laravel的http中間件還是遜色一些:

  • 需要對每個頁面程式碼包裝一層。

  • 即使使用者身分校驗不通過,小程式也不會阻塞頁面的渲染。若要取得使用者身分的非同步方法一分鐘才執行完,小程式頁面還是會展示出來,一分鐘之後才跳到登入頁。需要自己增加邏輯,例如在這一分鐘內,頁面展示空白內容。

#

以上是微信小程式開發頁面攔截器的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn