目录

小程序的按需登录的实现代码及思想

目录

小程序的按需登录的实现代码及思想

微信小程序的用户登录发生了改变,以前是进入小程序后就让用户强制登录再进行后续操作,但是现在不同了,要求用户在需要登录的页面才进行登录

比如:在首页展示商品时,没有必要知道用户的信息,就不需要登录,点击商品进入到商品详情页的时候,也不需要用户登录,当用户点击购买商品时才让用户登录

这种场景怎么实现呢?

我的做法(先说思想)

因为不同的页面需要登录的情况不同, 那么我们就在小程序的 自定义组件中  自定义一个登录的组件   在pages的页面中,哪个页面需要登录,就在哪个页面中引入这个组件  就可以实现按需登录

下面再说一说 这个登录组件的思想

登录的组件要考虑用户 有没有 授权 如果授权过,则把登录组件隐藏,如果没有授权过,则显示登录的组件 ,要求用户通过button按钮来进行 登录授权

用户成功授权后,利用登录组件的 triggerEvent 来通知 父页面去加载初始数据  (注意,此时父组件的onload已经加载过了,没用了,只能通过子组件的triggerEvent来初始化数据)

有的登录还需要 用户 token 如下图

https://i-blog.csdnimg.cn/blog_migrate/fb971598718def78da6846e0c2e177f5.png

上一下代码:

login组件的代码

// components/authorize/auth.js
import { Auth } from "../../model/auth.js";
let auth = new Auth();
let app = getApp();
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    isHidden:{
      type:Number,
      value:1    //1表示隐藏 0表示显示 
    },
    isAutoLoad:{
      type:Number,
      value:1    //1表示自动登录, 0表示在没有授权的的情况下也不会自动登录
    }

},

/**

- 组件的初始数据
  */
  data: {

},

//在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发。此时, this.data 已被初始化为 组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。
attached:function(){
//组件加载完成后,要调用自动登录的方法
this.setLoadStatus();
},

/**

- 组件的方法列表
  */
  methods: {
  setLoadStatus:function(){
  let _this = this;
  wx.getSetting({
  success:function(res){
  if (!res.authSetting['scope.userInfo']){
  //如果用户没有授权过,
  if(_this.data.isAutoLoad == 0) return //如果设置的 isAutoLoad 为 0 则不会自动登录
  if(_this.data.isAutoLoad == 1){
  //显示登录按钮,让用户点击 授权按钮登录
  _this.setData({
  isHidden:0
  })
  }
  }else{
  //如果用户是已经授权过的
  let token = app.globalData.token;
  if(token){
  //如果 token 存在
  _this.triggerEvent("userLoadFun", { "token":app.globalData.token });
  }else{
  //如果 token 不存在  
   //调用 auth model 中的 wxlogin 如果成功 就会记录 token
  auth.wxlogin().then(() => {
  return auth.wxCheckSession();
  }).then(() => {
  _this.setData({
  "isHidden": 1
  });
  //用户登录成功,调用页面中的函数来获取初始化数据
  _this.triggerEvent("userLoadFun", {"token":app.globalData.token});
  });
  }

          }
        }
      })

  },


    onGotUserInfo:function(e){
      //点击授权按钮
      let _this = this;
      auth.wxlogin().then(()=>{
        return auth.wxCheckSession();
      }).then(()=>{
        _this.setData({
          "isHidden":1
        });
        _this.triggerEvent("userLoadFun", { "token": app.globalData.token });
      });
    },

}
})

//model 层的代码   import { Auth } from “../../model/auth.js”; 这个文件是用来执行功能的一个类

import { Http } from '../utils/http.js';
let app = getApp();
class Auth extends Http{

setCode(code){
return this.request({
url:"login/setCode",
method:"post",
param:{
code:code
}
});
}

userLogin(iv, encryptedData){
return this.request({
url:"login/index",
method:"post",
param:{
iv,
encryptedData,
cache_key: wx.getStorageSync("cache_key")
}
})
}

wxlogin(){
let _this = this;
return new Promise(function(reslove,reject){
wx.login({
success(res){
if(res.code){
_this.request({
url:"login/setCode",
method:"post",
param:{
code:res.code
}
}).then((res)=>{//通过 login 得到 cache_key 其实就是 session_key 在后台的键值
wx.setStorageSync("cache_key", res.cache_key);
reslove();
});
}else{
reject();
}
},
})
});
}

//通过得到的 cache_key 可以得到用户的信息,传给后台,要么登录,要么新增用户

wxCheckSession(){
let _this = this;
return new Promise(function(reslove,reject){
wx.checkSession({
success() {
//session_key 未过期,并且在本生命周期一直有效
wx.getUserInfo({
withCredentials: true,
success: function (res) {
_this.userLogin(res.iv, res.encryptedData).then((res) => {
app.globalData.token = res.token;
app.globalData.isLogin = true;
reslove()
})
},
fail: function () {
reject();
_this.showToast('用户登录失败,请重试')
}
})
},
fail() {
reject();
// session_key 已经失效,需要重新执行登录流程
//重新登录
_this.wxlogin();
}
})
});
}

}

export { Auth };

封装的 http 基类的代码,用来做小程序的请求后台接口的基类

import { config } from "./config.js"

class Http{

constructor(){
this.baseUrl = config.baseUrl;
}

request({url,method="get",param={},header={}}){
this.showLoading();
return new Promise((resolve,reject)=>{
wx.request({
url: this.baseUrl + url,
method:method,
data:param,
header:header,
success:(res)=>{
if(res.data.code == 200){
this.hideLoading();
resolve(res.data.data);
}else{
this.hideLoading();
this.showToast(res.msg);
reject();
}
},
fail:(res)=>{
this.hideLoading();
this.showToast("网络请求出错,请重试");
reject();
}
})
})
}

showToast(msg){
wx.showToast({
title: msg,
image:"/images/error.jpg",
duration:1500,
mask:true
})
}

showLoading(){
wx.showLoading({
title: '连接中...',
})
}

hideLoading(){
wx.hideLoading()
}

}

export {Http}

page 页面;这里的 page 页面是一个获得优惠券的页面,领取时要用户的信息

<!--pages/user_get_coupon/index.wxml-->
<nav paramters= "{{ paramters }}" bindreturnback="returnback"></nav>
<view class="coupon-wrapper" style="margin-top:{{statusBarHeight+88}}rpx">
<block wx:for="{{couponList}}" wx:key="{{index}}">
<view class="c-wrapper">
<coupon-one ticketsPro="{{item}}"></coupon-one>
</view>
</block>
</view>
<auth binduserLoadFun="userLoadFun"></auth>

// pages/user_get_coupon/index.js
import { Coupon } from "../../model/coupon.js";
let coupon = new Coupon();
let app = getApp();
Page({

/**

- 页面的初始数据
  */
  data: {
  paramters:{
  nav:1,
  title:"领取优惠券",
  returnback:1
  },
  statusBarHeight: app.globalData.statusBarHeight,
  couponList:[]
  },

/**

- 生命周期函数--监听页面加载
  */
  onLoad: function (options) {

},

userLoadFun:function(e){
coupon.getCouponList().then((res)=>{
this.setData({
couponList:res
})
})
},

returnback:function(){
wx.navigateBack({
delta:1
})
},

/**

- 生命周期函数--监听页面初次渲染完成
  */
  onReady: function () {

},

/**

- 生命周期函数--监听页面显示
  */
  onShow: function () {

},

/**

- 生命周期函数--监听页面隐藏
  */
  onHide: function () {

},

/**

- 生命周期函数--监听页面卸载
  */
  onUnload: function () {

},

/**

- 页面相关事件处理函数--监听用户下拉动作
  */
  onPullDownRefresh: function () {

},

/**

- 页面上拉触底事件的处理函数
  */
  onReachBottom: function () {

},

/**

- 用户点击右上角分享
  */
  onShareAppMessage: function () {

}
})