微信小程序在创建初期会给一个获取用户信息的示例代码,我们今天就来解析一下小程序全局app.js运行方式及用户数据存储建议。
原版app.js代码:通过代码我们可以看到 在APP过程中先是调用了用户登陆wx.login 登陆成功之后我们还可以根据 code 通过服务器交互(CURL方式)获取到用户的openid sessionKey这些。
然后 通过 wx.getSetting 这个方法获取用户数据,并把用户数据存在 globalData 里的 userinfo变量中。
App({ onLaunch: function () { // 展示本地存储能力。 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) //console.log(logs) // 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log(res); } }) // 获取用户信息 wx.getSetting({ success: res => { //console.log("getSetting is:"+res); if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId console.log(res); this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) }, globalData: { userInfo: null, userOpenid: '' }})
在调用的时候 index.js里面,可以看到我把原来的代码全注释掉了,因为后来换了方法,但这个也可以先解析一下它的代码。
首先 用 if 来判断是否获取了 app.globalData.userInfo 为什么要加这个判断呢?在人家APP.JS里面有介绍,由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回,所以页面加载成功的时候有可能这个值还没返回过来,然后就有了 elseif 利用 callback的方式来获取用户信息。
// if (app.globalData.userInfo) { // console.log("初次加载,这时候应该还没有 app.globalData.userInfo"); // this.setData({ // userInfo: app.globalData.userInfo, // userOpenid:wx.getStorageSync('tureUserOpenID'), // hasUserInfo: true // }) // } else if (this.data.canIUse){ // // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // // 所以此处加入 callback 以防止这种情况 // app.userInfoReadyCallback = res => { // console.log("初次加载,这时候应该还没有 app.globalData.userInfo,所以在CALLBACK处获取用户信息"); // this.setData({ // userInfo: res.userInfo, // userOpenid:wx.getStorageSync('tureUserOpenID'), // hasUserInfo: true // }); // } // } else { // // 在没有 open-type=getUserInfo 版本的兼容处理 // console.log("如果用户没有同意的时候加载这个获取用户信息"); // wx.getUserInfo({ // success: res => { // app.globalData.userInfo = res.userInfo // this.setData({ // userInfo: res.userInfo, // userOpenid:wx.getStorageSync('tureUserOpenID'), // hasUserInfo: true // }) // } // }) // }
APP.JS运行流程解析:在初次打开小程序的时候 会默认指到首页上面,但首页加载与app.js加载是同时进行的。有可能APP.JS还没加载完成首页就加载好了,所以在首页调用的时候加了个判断 使用了callback的方式 防止获取不到用户数据。
当APP.JS加载完成之后,再点击其它页面的时候,这个APP.JS里面的东西不会重新加载,因为它的代码是写在 onLaunch: function () 时面的。这个代表页面加载时运行。
经过测试发现 APP.JS只在加载的时候运行一次,而且当运行完成之后再点击其它页面之时 app.globalData.userInfo 已经有值了,其它页面调用的时候就可以走这一层,直接去拿用户信息。
但这样的话每次想要使用用户信息数据之时都需要写JS去获取,感觉很麻烦。
所以我选择了在 APP.JS中获取完用户信息后把用户信息用全局存储的方式存起来。
经过测试发现不用JS,直接使用全局存储就可以了。这样就感觉方便很多。
总结:
- APP.JS里面获取用户数据,只在加载之时运行一次,加载完成之后再点任何页面都不会重新加载。
- index.js加载有可能会比APP.JS还快,所以用JS代码调用用户信息的时候需要做判断,先判断一下数组有没有值,如果没有就使用CALLBACK的方式去获取。
- 把用户信息通过全局存储的方式存在APP.JS里面,在所有页面直接调用即可,感觉这样很省心,但不知道有没有什么暗坑。