微信小程序最近被吐槽最多的一个更改,就是用户使用wx.getUserInfo(开发和体验版)时不会弹出授权,正式版不受影响。现在授权方式是需要引导用户点击一个授权按钮,然后再弹出授权。我最近围绕这个做了一些研究,来看看我是如何做好这个授权。
1.用户进来一个页面时,按照微信小程序的生命周期,开始解析onLoad里面的内容。
所以我们在第一步,就把代码放在这里,看看全局变量是否已经有值,
2.如果之前没有授权,则查看用户是否有请求一个授权登录的按钮,
3.最后查阅这个函数的授权结果,是成功返回还是失败。代码如下:
onLoad: function () { if (app.globalData.userInfo) { console.log(1) this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse){ console.log(2) // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.userInfoReadyCallback = res => { console.log(12) app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { console.log(3) // 在没有 open-type=getUserInfo 版本的兼容处理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) }, fail:res=>{ console.log(4); this.setData({ getUserInfoFail:true }) } }) } },
第二步:通常我们这里会进入第二步,允许使用按钮提示用户授权。在onLoad周期里面我们没获取到用户是否有成功授权,我们下一周期onShow,在这里,我们就可以查阅授权的状态,如果进入了fail操作,说明还没有授权,在失败的时候,我们赋值告知授权失败,我们页面根据这个状态值,来显示需要用户点击授权。代码如下:
login: function () { console.log(111) var that = this // if (typeof success == "function") { // console.log(6); // console.log('success'); // this.data.getUserInfoSuccess = success // } wx.login({ success: function (res) { var code = res.code; console.log(code); wx.getUserInfo({ success: function (res) { console.log(7); app.globalData.userInfo = res.userInfo that.setData({ getUserInfoFail: false, userInfo: res.userInfo, hasUserInfo: true }) //平台登录 }, fail: function (res) { console.log(8); console.log(res); that.setData({ getUserInfoFail: true }) } }) } }) },
页面xml中根据这个getUserInfoFail来显示按钮。
<button wx:if="{{!hasUserInfo && canIUse && getUserInfoFail}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
当用户点击授权后,弹出一个弹窗,提示他授权,这个时候调用的是getUserInfo这个函数,代码如下:
getUserInfo: function(e) { console.log(5); console.log(e) if(e.detail.userInfo){ app.globalData.userInfo = e.detail.userInfo this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) }else{ this.openSetting(); } },
如果我们可以获取到detail.userInfo的值,说明参数正确,用户点击了允许授权。如果用户点击拒绝,这个时候我们就要调用openSetting这个函数。这个函数主要是打开授权的地方,有兼容性问题,低版本不支持。
openSetting: function () { var that = this if (wx.openSetting) { wx.openSetting({ success: function (res) { console.log(9); //尝试再次登录 that.login() } }) } else { console.log(10); wx.showModal({ title: '授权提示', content: '小程序需要您的微信授权才能使用哦~ 错过授权页面的处理方法:删除小程序->重新搜索进入->点击授权按钮' }) } }
如果用户进入了授权页后,点击允许我们获取用户信息,返回成功时,我们执行login这个函数,这时,我们就可以进入getuserInfo() 里面拿到授权的信息了。那么头像、用户信息和其它一些个人的资料都可以查到了。
完整的index.js如下:
//index.js //获取应用实例 const app = getApp() Page({ data: { motto: 'Hello World', userInfo: {}, hasUserInfo: false, getUserInfoFail:false, canIUse: wx.canIUse('button.open-type.getUserInfo') }, //事件处理函数 bindViewTap: function() { wx.navigateTo({ url: '../logs/logs' }) }, onShow:function(){ this.login(); }, onLoad: function () { if (app.globalData.userInfo) { console.log(1) this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse){ console.log(2) // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.userInfoReadyCallback = res => { console.log(12) app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { console.log(3) // 在没有 open-type=getUserInfo 版本的兼容处理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) }, fail:res=>{ console.log(4); this.setData({ getUserInfoFail:true }) } }) } }, getUserInfo: function(e) { console.log(5); console.log(e) if(e.detail.userInfo){ app.globalData.userInfo = e.detail.userInfo this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) }else{ this.openSetting(); } }, login: function () { console.log(111) var that = this // if (typeof success == "function") { // console.log(6); // console.log('success'); // this.data.getUserInfoSuccess = success // } wx.login({ success: function (res) { var code = res.code; console.log(code); wx.getUserInfo({ success: function (res) { console.log(7); app.globalData.userInfo = res.userInfo that.setData({ getUserInfoFail: false, userInfo: res.userInfo, hasUserInfo: true }) //平台登录 }, fail: function (res) { console.log(8); console.log(res); that.setData({ getUserInfoFail: true }) } }) } }) }, //跳转设置页面授权 openSetting: function () { var that = this if (wx.openSetting) { wx.openSetting({ success: function (res) { console.log(9); //尝试再次登录 that.login() } }) } else { console.log(10); wx.showModal({ title: '授权提示', content: '小程序需要您的微信授权才能使用哦~ 错过授权页面的处理方法:删除小程序->重新搜索进入->点击授权按钮' }) } } })
index.xml如下:
<!--index.wxml--> <view class="container"> <view class="userinfo"> <button wx:if="{{!hasUserInfo && canIUse && getUserInfoFail}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button> <block wx:if="{{hasUserInfo}}"> <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </block> </view> <view class="usermotto"> <text class="user-motto">{{motto}}</text> </view> </view>
至此,我们就完成了用户的流程了。