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欢迎指正。

相关文章
相关标签/搜索