美文网首页为了梦想微信小程序开发微信小程序开发
小程序开发六:登录Login页面的实现与讲解

小程序开发六:登录Login页面的实现与讲解

作者: Mr姜饼 | 来源:发表于2019-12-13 17:31 被阅读0次

    上一节:我们简单介绍了一下项目的基本模板,这里做一下优化,因为默认的模板是index,我们理解为login登录页面,这样不太好理解,所以我这边稍作改动,我们将index的页面重新命名为login页面,然后删掉默认给出的logs页面,

    修改前:


    修改前

    修改后:


    修改后

    下面正式讲解login页面的处理逻辑和页面布局:

    首先我们来看源代码(注释已写上)

    login.wxml

    <view class="container">//设置容器
      <view class="userinfo">//设置容器为“userinfo”的盒子
        <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>//绑定”用户信息“数据,如果没有获得用户的信息,则显示获取按钮,并绑定获取用户信息的方法
        <block wx:else>//否则显示用户的头像和昵称
          <image src="{{userInfo.avatarUrl}}" mode="cover"></image>
          <text class="userinfo-nickname">{{userInfo.nickName}}</text>
        </block>
      </view>
      <view class="usermotto">//helloword的text
        <text class="user-motto">{{motto}}</text>
      </view>
    </view>
    

    login.wxss

    页面上的view的样式设置,这里不过多介绍

    login.js(重点)

    Page({
     data: {//设置4个参数
       motto: 'Hello World',//座右铭
       userInfo: {},//用户信息
       hasUserInfo: false,//是否获得了用户信息
       canIUse: wx.canIUse('button.open-type.getUserInfo')//判断小程序的API,回调,参数,组件等是否在当前版本可用
     },
     //事件处理函数
     onLoad: function () {//页面的启动函数
        if (app.globalData.userInfo) {
         this.setData({//绑定数据
           userInfo: app.globalData.userInfo,
           hasUserInfo: true
         })
       } else if (this.data.canIUse){
         // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
         // 所以此处加入 callback 以防止这种情况
         app.userInfoReadyCallback = res => {
           this.setData({//绑定数据
             userInfo: res.userInfo,
             hasUserInfo: true
           })
         }
       } else {
         // 在没有 open-type=getUserInfo 版本的兼容处理
         wx.getUserInfo({
           success: res => {
             app.globalData.userInfo = res.userInfo
             this.setData({//绑定数据
               userInfo: res.userInfo,
               hasUserInfo: true
             })
           }
         })
       }
     },
     getUserInfo: function(e) {//获取用户信息之后的回调,配合"bindgetuserinfo"的button使用
       console.log(e)
       app.globalData.userInfo = e.detail.userInfo
       this.setData({//绑定数据
         userInfo: e.detail.userInfo,
         hasUserInfo: true
       })
     }
    })
    

    上面所说的数据绑定是这么个流程:

    1.在.xml文件中,view(text、image、button等等.....)与.js文件中设置的数据(如上面代码中的"hasUserInfo")进行捆绑,并随时监听此数据的变化,然后做出相应的变化(如上面代码中的,如果hasUserInfo为flase时,则显示button;反之则隐藏)

    2.在.js文件中,处理业务逻辑,并对设置的数据进行操作和赋值,同时刷新绑定数据的view(如在获取到用户信息的时候,"hasUserInfo"变为true,这时候在.wxml中绑定的button则进行隐藏,不再显示)

    .wxml进行负责显示的样式

    .js处理显示的内容

    显示图

    业务逻辑的分析与实现

    业务场景:

    1.用户首次进入小程序,发起注册请求,注册完成之后,进行登录,登录成功之后,进入动态首页

    2.用户再次进入程序,已成功检测用户注册过,直接进行登录,进入动态首页


    那么开始编写逻辑吧

    首先我们.xml中编写一个登录的按钮,并且绑定一个”userLogin“的函数

    <button class="loginBtn" catchtap="userLogin">登录</button>
    

    在点击了按钮之后,执行js文件中的userLogin函数

     userLogin: function() {
        //先注册用户 然后登陆
        var userInfoData = wx.getStorageSync('userInfoData');//读取本地是否存在用户信息(首次进入小程序的情况,肯定不存在用户信息;只有在用户注册并且登录的情况下,才会去保存本地用户信息)
        if (!userInfoData) {
          console.log('用户没有注册登录过');
          this.registerAccount();//注册用户
        } else {
          console.log('用户注册登录过');
          this.loginAccount(userInfoData.username);//登录(为什么本地有了用户信息却还要登录呢,一般来说,这里的登录是为了方便刷新用户资料信息,便于同步)
        }
      }
    

    思路详解:
    首先我们读本是否有本地的用户数据,不存在,则进行注册然后登录;存在的话,重新登录,便于刷新用户数据。

    重点来看注册的registerAccount()函数和登录的loginAccount()函数;

    registerAccount()

          /*注:
    这里因为我调的接口是来自移动端的接口设计(强调),所以我这边传的三个参数为:
    username(用户名)
    nick_nam(注册用户的昵称)
    password(注册用户的密码)
    
    正确的小程序的注册参数一般为:
    js_code( wx.login登录时获取的 code,用于后续获取session_key)
    encryptedData ( 包括敏感数据在内的完整用户信息的加密数据)
    iv( 加密算法的初始向量)
          */
      registerAccount: function() {
        var that = this;
        var paraData = {
          username: "TEST002",//(切记,真正的这里的传参要使用唯一的标志符号)
          nick_name: this.data.userInfo.nickName,
          password: "111111"(因为我们是直接微信授权)
        }
        var cookie = wx.getStorageSync('cookie');
        if (cookie) { //保险起见 先移除掉
          wx.removeStorageSync('cookie');
        }
        requestTool.postRequest("/user/register", paraData, that.registerGetSuccess, that.registerGetFailed);
      },
      //注册成功的回调
      registerGetSuccess: function(data) {
        console.log("注册成功");
        var userName = data.username;
        this.loginAccount(userName);
      },
      //注册失败的回调
      registerGetFailed: function(res) {
        console.log("注册失败" + res);
      },
    

    loginAccount()

      loginAccount: function(userName) {
        var that = this;
        var paraData = {
          username: userName,//注册时使用的用户名
          password: "111111"//(前面注册的时候,我们默认用的111111的密码)
        }
        var cookie = wx.getStorageSync('cookie');
        if (cookie) { //保险起见 先移除掉
          wx.removeStorageSync('cookie');
        }
        requestTool.postRequest("/user/login", paraData, that.loginGetSuccess, that.loginGetFailed);
    
      },
    
      loginGetSuccess: function(data) {
        console.log("登录成功" + data);
        //填充数据
        var userInfoData = {};
        userInfoData["id"] = data._id;
        userInfoData["username"] = data.username;
        userInfoData["nick_name"] = data.nick_name;
        userInfoData["age"] = data.age;
        userInfoData["sex"] = data.sex;
        userInfoData["avatar"] = this.data.userInfo.avatarUrl;//因为后台会返回一个默认的头像地址,这里我们将微信的头像地址替换此数据。
        //向缓存中存入数据“ userInfoData”
        wx.setStorageSync('userInfoData', userInfoData);
    
        //去到动态主页面首页(tab页面)
        //注意:凡是去到tab页面,千万不能用wx.navigateTo 或者 wx.redirectTo,要使用wx.switchTab或者wx.lanchTo
        wx.switchTab({
          url: '../home/home',
        })
      },
    
      loginGetFailed: function(res) {
        console.log("登录失败" + res);
      },
    

    补充:

    上述的网络请求,已经封装到utils文件夹中
    (另外的几个文件后面的开发中会一个个提到,这次只讲request.js)


    request.js

    上代码:

    var app = getApp();
    //项目URL相同部分,减轻代码量,同时方便项目迁移
    //这里因为我是本地调试,所以host不规范,实际上应该是你备案的域名信息
    
    /**
     * POST请求,
     * URL:接口
     * postData:参数,json类型
     * doSuccess:成功的回调函数
     * doFail:失败的回调函数
     */
    function postRequest(urlPath, postData, doSuccess, doFail) {
      var requestUrl = app.globalData.mianServerUrl + urlPath;
      var header = {};
      header["content-type"] =  "json";
      header["meme-app"] = "CCC";
      var cookie = wx.getStorageSync('cookie');
      if(cookie){
        header["cookie"] = cookie;
      }
      wx.request({
        //项目的真正接口,通过字符串拼接方式实现
        url: requestUrl,
        header: header,
        data: postData,
        method: 'POST',
        success: function (res) {
          //参数值为res.data,直接将返回的数据传入
          if (urlPath == '/user/login'){//存cookie
            var cookie = res.header.Cookie;
            if(!cookie){
              cookie = res.header.cookie;
            }
            wx.setStorageSync('cookie', cookie);
            console.log(res.header + '获得的头部s');
          }
          doSuccess(res.data);
        },
        fail: function (res) {
          doFail(res);
        },
        
      })
    }
    
    /**
     * GET请求,
     * urlPath:接口
     * paraData
     * doSuccess:成功的回调函数
     * doFail:失败的回调函数
     */
    function getRequest(urlPath,paraData, doSuccess, doFail) {
      
      var requestUrl = app.globalData.mianServerUrl + urlPath;
      var header = {};
      header["content-type"] = "json";
      header["meme-app"] = "CCC";
      var cookie = wx.getStorageSync('cookie');
      if (cookie) {
        header["cookie"] = cookie;
      }
      wx.request({
        url: requestUrl,
        data: paraData,
        header: header,
        method: 'GET',
        success: function (res) {
          doSuccess(res.data);
        },
        fail: function (res) {
          console.log(res);
          doFail();
        },
      })
    }
    
    /**
     * module.exports用来导出代码
     * js文件中通过var call = require("../util/request.js")  加载
     * 在引入引入文件的时候"  "里面的内容通过../../../这种类型,小程序的编译器会自动提示,因为你可能
     * 项目目录不止一级,不同的js文件对应的工具类的位置不一样
     */
    
    module.exports = {
      postRequest: postRequest,
      getRequest: getRequest
    }
    

    注:
    文件中的
    var requestUrl = app.globalData.mianServerUrl + urlPath;
    需要在app.js文件中定义:

     globalData: {
         mianServerUrl: "https://api.ytqig.cn"
      }
    

    在需要用到此封装的request.js时候,都需要进行引入
    我在login.js文件中也引入了

    var requestTool = require("../../utils/request.js");
    

    当用户注册并且登录成功之后,进进入了home页面了

     wx.switchTab({//进入首页
          url: '../home/home',
        })
    

    注意:一旦有页面的显示,必须要在app.json中进行插入和申明:

     "pages": [
        "pages/login/login",
        "pages/home/home"
      ],
    

    好了,我们来编译下项目,并且来分析一下我们的数据存储过程吧;

    1.首先我们是第一次进入小程序,我们先进行授权,授权成功之后,获得到微信的头像和昵称,用于注册时候的传参;
    2.点击登录按钮,执行registerAccount()函数;
    3.注册成功后,执行loginAccount()
    4.登录成功之后,执行wx.swtichTab,进入home页面

    补充说明:

    上述讲到的数据请求wx.request(),本文只是先简单地过渡使用,并未对其介绍具体的使用方法,对此大家没有看太明白,也没多大的关系;关于数据请求,大家不妨接着往后面的内容看,我会在动态首页的页面具体讲到此函数方法的使用,到时候大家再回过头来看这一节,就能很清楚地明白这里的数据请求了(为什么我这里先要提出这个概念了,因为登录注册是项目的初始页面,这块涉及到了接口的使用,所以就粗略地写了下)

    特别说明:

    本文以及后续所有的内容,重点在于为大家分析项目的逻辑实现和讲解;至于接口失败或者错误,可能是接口过期失效了,有问题欢迎大家随时提问,谢谢。

    完结:

    传送门:
    七:动态首页Home的实现与讲解

    相关文章

      网友评论

        本文标题:小程序开发六:登录Login页面的实现与讲解

        本文链接:https://www.haomeiwen.com/subject/ylkfnctx.html