微信小程序登录获取用户信息并缓存用户信息及封装监听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方法即可;