HBuilder mui登陸和訪問控制教程--轉載

HBuilder mui登陸和訪問控制教程css

mui中提供了登陸的模板頁,可是對於登陸後各個頁面的訪問控制,刷新等並無官方的推薦方案。我在這裏簡單說一種初級的解決方案吧,確定有不足指出,歡迎批評指正。html

第一節中建立移動APP項目的時候選擇的是"mui項目",只引入了默認的js和css等文件,沒有登陸模板。要使用默認登陸模板,能夠建立的時候選擇"mui登陸模板"。如今建立一個名爲muiLogin的"mui登陸模板"項目:java

這裏寫圖片描述

能夠看到此次多了很多東西。經過manifest.json能夠發現,入口文件時login.html,咱們就從login.html開始。web

從plusReady函數開始看起。ajax

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<code><code><code><code>$.plusReady(function() {
     plus.screen.lockOrientation( "portrait-primary" );
     var settings = app.getSettings();
     var state = app.getState();
     var mainPage = $.preload({
         "id" : 'main' ,
         "url" : 'main.html'
     });
     var main_loaded_flag = false ;
     mainPage.addEventListener( "loaded" ,function () {
         main_loaded_flag = true ;
     });
     var toMain = function() {
         //使用定時器的緣由:
         //可能執行太快,main頁面loaded事件還沒有觸發就執行自定義事件,此時必然會失敗
         var id = setInterval(function () {
             if (main_loaded_flag){
                 clearInterval(id);
                 $.fire(mainPage, 'show' , null );
                 mainPage.show( "pop-in" );
             }
         }, 20 );
     };
     //檢查 "登陸狀態/鎖屏狀態" 開始
     if (settings.autoLogin && state.token && settings.gestures) {
         $.openWindow({
             url: 'unlock.html' ,
             id: 'unlock' ,
             show: {
                 aniShow: 'pop-in'
             },
             waiting: {
                 autoShow: false
             }
         });
     } else if (settings.autoLogin && state.token) {
         toMain();
     } else {
         app.setState( null );
         //第三方登陸
         var authBtns = [ 'qihoo' , 'weixin' , 'sinaweibo' , 'qq' ]; //配置業務支持的第三方登陸
         var auths = {};
         //...
     }
}
</code></code></code></code>

先經過.preload預加載了main.html(就是mui,這是個閉包函數,mui做爲參數$傳進來的,詳情百度JavaScript 閉包)。json

toMain跳轉主頁面更新用戶信息

而後是一個跳轉到主頁面的toMain函數,能夠看到這裏監聽了main頁面的loaded事件,當main加載完畢後,這裏就將標誌向量main_loaded_flag置爲true,toMain中循環判斷這個變量,當這裏爲true時,觸發main的show事件,而後在main中,show事件的響應函數從app.getState()中讀取用戶名,顯示在界面。這就完成了用戶登陸後主界面的用戶名顯示。服務器

app.getState和app.setState

上面用到了app.getState(),這是定義在js/app.js中的,不妨去看下都作了什麼。閉包

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<code><code><code><code><code> /**
  * 獲取當前狀態
  **/
owner.getState = function() {
     var stateText = localStorage.getItem( '$state' ) || "{}" ;
     return JSON.parse(stateText);
};
 
/**
  * 設置當前狀態
  **/
owner.setState = function(state) {
     state = state || {};
     localStorage.setItem( '$state' , JSON.stringify(state));
};
</code></code></code></code></code>

能夠看到這兩個是對localStorage的存取作了封裝,是一個字典對象,這是個很不錯的想法,能夠將用戶登陸後的全部狀態信息記錄在state裏面,包括用戶信息,是否自動登陸,用戶餘額,訂單列表頁的最新和最舊ID等都保存下來,用戶註銷後直接把state置爲null就能夠了,再次登陸後再設置state。app

上面的登陸就是這樣作的,登陸成功後保存用戶信息在state裏面,而後觸發涉及用戶的main頁面的事件,main頁面裏自定義事件的響應函數能夠從state裏讀取信息並更新。ide

登陸部分

登陸這裏先判斷了是否運行自動登陸以及是否設置了手勢解鎖。而後按狀況決定是手勢解鎖仍是直接登陸或者顯示登陸界面。

點擊登陸按鈕後,會調用app的login函數驗證登陸信息,驗證正確就會調用toMain跳轉到主頁面。

訪問控制

登錄部分很明瞭,可是大部分app是容許用戶在不登陸的狀況下瀏覽部分頁面的,若是用戶訪問的頁面須要登陸再自動跳轉到登陸頁面。

這裏就須要對登陸驗證作個封裝,畢竟每次驗證頁面的時候,都從state裏面判斷一下用戶是否登陸了,以及是否容許自動登陸,自動登陸是否成功,是否顯示登陸界面是件很麻煩的事。

咱們但願達到這種效果,若是用戶點擊"個人"頁面,經過如下代碼自動進行訪問控制:

?
1
2
3
4
5
6
7
8
9
<code><code><code><code><code><code><code>mui( '#my' )[ 0 ].addEventListener( 'tap' ,function(){
     app.loginRequired(function(){
         mui.openWindow({
             url: 'my.html' ,
             id: 'my'
         });
     });
});
</code></code></code></code></code></code></code>

只多了一行:app.loginRequired,若是某個頁面須要登陸才能訪問,就把登陸後執行的代碼做爲回調函數傳給app.loginRequired,由它進行自動登陸和登陸不成功的跳轉。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<code><code><code><code><code><code><code><code><code><code> /**
  * 要求登錄後才能執行回調函數
  * @param {Object} callback 已登陸或自動登陸成功執行,不然跳轉到登陸界面
  */
owner.loginRequired=function(callback){
     var state=owner.getState();
     if (state.isLogin){ //已登陸,直接執行
         callback();
     } else {
         owner.tryAutoLogin(function(data){
             if (data.Code== 1 ){ //自動登陸成功則執行回調函數
                 callback();
             } else { //自動登陸失敗,顯示登陸頁面
                 var v=plus.webview.getWebviewById( 'login' );
                 if (!v){
                     mui.toast( 'error:cannot find login' );
                 } else {
                     v.show( 'slide-in-right' , 300 );
                 }
             }
         });
     }
};
</code></code></code></code></code></code></code></code></code></code>

爲了確保上面能找到登陸頁面,須要先預加載login頁面,因爲主頁面是main,再也不是login了,能夠在main裏面預加載login.html,而後這裏就會找到login的webview

看到裏面調用了一個tryAutoLogin的自動登陸函數,這個函數嘗試用保存在state中的上次登陸信息自動ajax請求服務器登陸。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<code><code><code><code><code><code><code><code><code><code><code><code> /**
  * 嘗試自動登陸
  * @param {Function} callback 回調函數,接收一個字典參數data,data.Code>0表示登陸成功
  */
owner.tryAutoLogin=function (callback){
     var state=owner.getState();
     if (state.isLogin){
         callback({Code: 1 });
         return ;
     }
     var user=JSON.parse(localStorage.getItem( '$user' ));
     //須要在登陸或註冊成功時將用戶信息保存在localStorage中
     var settings=owner.getSettings();
     if (settings.autoLogin&&user&&user.name) {
         owner.login(user,callback);
     } else {
         callback({Code:- 1 });
     }
}
</code></code></code></code></code></code></code></code></code></code></code></code>

tryAutoLogin的主要工做就是判斷是否容許自動登陸,若是容許就調用login方法嘗試登陸,並將回調函數也傳遞過去。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<code><code><code><code><code><code><code><code><code><code><code><code><code> /**
  * 用戶登陸
  **/
owner.login = function(loginInfo, callback) {
     callback = callback || $.noop;
     loginInfo.Method= 'Login' ; //告訴服務器執行哪一個函數
     $.ajax(owner.server,{ //服務器地址
         data:loginInfo,
         success:function(data){
             if (data.Code== 1 ){
                 plus.nativeUI.toast( '登陸成功' );
                 var state=owner.defaultState; //登陸後用默認State覆蓋現有的State
                 state.isLogin= true ; //標記已登陸
                 state.user=data.Data; //保存用戶信息
                 owner.setState(state);
                 //保存登陸信息
                 localStorage.setItem( '$user' , JSON.stringify(loginInfo));
 
                 //通知資金變更頁面刷新
                 var moneyChange=plus.webview.getWebviewById( 'moneyChange' );
                 if (moneyChange){
                     mui.fire(moneyChange, 'show' );
                 }
                 //通知其餘用戶相關頁面更新
             }
             callback(data);
         },
         error:function(msg){
             callback({
                 Code:- 3 ,
                 Msg: '沒法鏈接到服務器'
             });
         }
     });
};
</code></code></code></code></code></code></code></code></code></code></code></code></code>

login函數中有一句是defaultState,這個就是存儲的默認用戶狀態,用戶註銷再次登陸後就應該用這個替換上次用戶的狀態。防止信息錯亂。

經過以上三個函數,就完成了頁面登陸的自動驗證和訪問控制,使得總體邏輯比較清晰,代碼若有bug歡迎指正。

相關文章
相關標籤/搜索