微信小程序登录获取用户信息并缓存用户信息及封装监听data数据的变化的js封装

1.先在app.js里写一个方法,然后在onload里调用即可,具体说明看代码

 loadToData:function(){
    var that = this;
    var user = wx.getStorageSync('user') || {};
    var userInfo = wx.getStorageSync('userInfo') || {};
    console.log('缓存的数据', user, userInfo)
    if ((user && user.userId) || this.globalData.userInfo.nickName) {
      wx.showTabBar();
    } else {
      wx.hideTabBar()
    }
    if ((!user.openid || (user.expires_in || Date.now()) < (Date.now() + 600)) && (!userInfo.nickName)) {
      wx.login({
        //获取code
        success: function (res) {
          var code = res.code //返回code
          wx.getSetting({
            success: res => {
              if (res.authSetting['scope.userInfo']) {
                // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
                wx.getUserInfo({
                  success: res => {
                    // 可以将 res 发送给后台解码出 unionId
                    that.globalData.userInfo = res.userInfo;
                    var userObj = {};
                    var userInfoObj = {};
                    userObj.encryptedData = res.encryptedData;
                    userObj.iv = res.iv;
                    userObj.expires_in = Date.now() + 24 * 7 * 60 * 60;
                    userInfoObj.nickName = res.userInfo.nickName;
                    userInfoObj.avatarUrl = res.userInfo.avatarUrl;
                    userInfoObj.gender = res.userInfo.gender;
                    wx.request({
                      url: 'https://api.weixin.qq.com/sns/jscode2session?appid=' + that.globalData.appid + '&secret=' + that.globalData.secret + '&js_code=' + code + '&grant_type=authorization_code',
                      data: {},
                      header: {
                        'content-type': 'application/json'
                      },
                      success: function (res) {
                        var openid = res.data.openid; //返回openid
                        userObj.openid = openid;
                        that.globalData.openid = res.data.openid;
                        apiModel.verificationWecat({ usrWecat: userObj.openid }).then(res => {
                          console.log('请求登录是否成功', res.code == '200', userObj.openid, res)
                          if (res.code == '200') {
                            console.log('请求登录成功', res.data.usrId, res)
                            that.globalData.userId = res.data.usrId;
                            userObj.userId = res.data.usrId;
                            wx.setStorageSync('userInfo', userInfoObj);
                            wx.setStorageSync('user', userObj);
                          } else {
                            var param = {
                              usrName: userInfoObj.nickName,
                              usrWecat: userObj.openid,
                            }
                            apiModel.addUser(param).then(res => {
                              console.log('添加注册用户成功', res.data.usrId, param, res)
                              that.globalData.userId = res.data.usrId;
                              userObj.userId = res.data.usrId;
                              wx.setStorageSync('userInfo', userInfoObj);
                              wx.setStorageSync('user', userObj);
                            })
                          }
                        });
                      }
                    });
                    
                  }
                })
              }
            }
          });
        }
      })
    }
  },
  globalData: {
    openid:null,//传给后台用于给用户标识注册的id
     currentShow: 1,
    userInfo: {},//用户头像、昵称
    userId:null,//用户id
    appid: 'wx4f18a4fcbfb12f49f239e',//appid需自己提供,此处的appid我随机编写
    secret: '06164999eaf9f5402f0024419f9a09179f9a',//secret需自己提供,此处的secret我随机编写
  }

2.其实我们在启动小程序的时候并没有自己弹出获取用户信息的弹框,这个得自己写一个button来获取用户信息,然后再进行相应的操作

index.wxml:

<view class="cont1" wx:if="{{!hasUserInfo && canIUse}}">
<view class="zw"></view>
  <view class="userinfo">
    <view class="toast-title">提示</view>
    <view class="toast-content">将获取你的个人信息头像、昵称等</view>
    <button class="toast-true" open-type="getUserInfo" bindgetuserinfo="getUserInfo">确认</button>
  </view>
</view>
<view wx:else>
  <view hidden="{{currentShow ? true : false}}">
    <merchantIndex />
  </view>

  <view hidden="{{!currentShow ? true : false}}">
     <studentindex />
  </view>
</view>

index.js

const app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // 1---->学生
    // 0---->管理
    currentShow: app.globalData.currentShow,
    hasUserInfo: wx.getStorageSync('hasUserInfo'),
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  
 
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    app.setWatcher(this);
    if (app.globalData.userInfo.nickName) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
      wx.setStorageSync('hasUserInfo', true)
    } else if (this.data.canIUse) {
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
        wx.setStorageSync('hasUserInfo', true)
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
          wx.setStorageSync('hasUserInfo', true)
          app.loadToData();
        }
      })
    }
  },

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

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    console.log("onshow")
  },
  getUserInfo: function (e) {
    app.globalData.userInfo = e.detail.userInfo
    console.log('app.globalData.userInfo', app.globalData.userInfo)
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
    wx.setStorageSync('hasUserInfo', true)
    app.loadToData()
  },
  watch: {
    userInfo: function (newobj, oldobj) {
      if (newobj.nickName) {
        wx.showTabBar();
      }
    }
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    console.log("onHide")
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    console.log("onUnload")
  },

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

  },

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

  },

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

  }
})

其中有一个watch.js的封装

/**
 * 设置监听器
 */
export function setWatcher(page) {
  let data = page.data;
  let watch = page.watch;
  // if (!watch.userInfo.nickName){
    
  // };
  Object.keys(watch).forEach(v => {
    let key = v.split('.'); // 将watch中的属性以'.'切分成数组
    let nowData = data; // 将data赋值给nowData
    for (let i = 0; i < key.length - 1; i++) { // 遍历key数组的元素,除了最后一个!
      nowData = nowData[key[i]]; // 将nowData指向它的key属性对象
    }
    let lastKey = key[key.length - 1];
    // 假设key==='my.name',此时nowData===data['my']===data.my,lastKey==='name'
    let watchFun = watch[v].handler || watch[v]; // 兼容带handler和不带handler的两种写法
    let deep = watch[v].deep; // 若未设置deep,则为undefine
    observe(nowData, lastKey, watchFun, deep, page); // 监听nowData对象的lastKey
  })
}
/**
 * 监听属性 并执行监听函数
 */
function observe(obj, key, watchFun, deep, page) {
  var val = obj[key];
  // 判断deep是true 且 val不能为空 且 typeof val==='object'(数组内数值变化也需要深度监听)
  if (deep && val != null && typeof val === 'object') {
    Object.keys(val).forEach(childKey => { // 遍历val对象下的每一个key
      observe(val, childKey, watchFun, deep, page); // 递归调用监听函数
    })
  }
  let that = this;
  Object.defineProperty(obj, key, {
    configurable: true,
    enumerable: true,
    set: function (value) {
      watchFun.call(page, value, val); // value是新值,val是旧值
      val = value;
      if (deep) { // 若是深度监听,重新监听该对象,以便监听其属性。
        observe(obj, key, watchFun, deep, page);
      }
    },
    get: function () {
      return val;
    }
  })
}
module.exports = {
  setWatcher: setWatcher
}

调用watch.js的方法

const watch = require("./utils/watch.js");
App({
  setWatcher(page) {
    watch.setWatcher(page);
  },})

然后在其他页面的应用可见index.js:在onload里调用,然后再在页面写监听data里相应数据的变化watch方法即可;
原文地址:https://www.cnblogs.com/Dark-fire-liehuo/p/11981807.html