0. 引言
微信小程式為了優化使用者體驗,取消了在進入小程式時立馬出現授權視窗。需要使用者主動點選按鈕,觸發授權視窗。
那麼,在我實踐過程中,出現了以下問題。
1. 無法彈出授權視窗 2. 希望在使用者已經授權的情況下,不顯示按鈕
1. 具體實現
app.js的onLaunch()函式中,新增獲取使用者個人資訊的程式碼段。實現在使用者已經授權的情況(例如第二次開啟小程式時)下,自動獲取使用者個人資訊,而不需要使用者的授權。
// 獲取使用者資訊 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { console.log("app: " + "使用者已經授權") // 已經授權,可以直接呼叫 getUserInfo 獲取頭像暱稱,不會彈框 wx.getUserInfo({ success: res => { // 可以將 res 傳送給後臺解碼出 unionId this.globalData.userInfo = res.userInfo console.log(this.globalData.userInfo) this.globalData.hasUserInfo = true // 由於 getUserInfo 是網路請求,可能會在 Page.onLoad 之後才返回 // 所以此處加入 callback 以防止這種情況 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } }, fail: (res) => { console.log("app: " + "獲取使用者資訊失敗") } }) }else { console.log("app: " + "使用者暫時未授權") } } })
me.wxml中新增授權按鈕(具體的頁面根據大家的實際情況)。這裡的button元件必須按照如下的形式。
<button open-type="getUserInfo" bindgetuserinfo="你自己定義函式"></button>
<block wx:if="{{!hasUserInfo}}"> <image src='../../images/icon/wechat.png'></image> <button open-type="getUserInfo" bindgetuserinfo="getUserInfo">微信授權登入</button> </block>
效果這樣,具體的樣式根據大家的喜好更改
me.js中新增如下變數和方法,在使用者之前沒有授權的情況下,需要使用者主動點選按鈕。
data: { userInfo: null, hasUserInfo: false }, getUserInfo: function(e) { console.log("me: " + "使用者點選授權") if(e.detail.userInfo){ this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) app.data.userInfo = this.userInfo app.data.hasUserInfo = true } }
2. 無法彈出授權視窗
這裡一定要注意
授權視窗只會在使用者第一次授權時出現,也就是,只會出現一次!!
在微信小程式開發工具裡,需要我們清除所有快取
3. 已經授權的情況下,不顯示按鈕
由於使用者已經授權的時候,app.js會獲取使用者個人資訊(而不是在使用者點選授權按鈕時獲取),但是這個過程是非同步的。
可以看到我們的授權按鈕的出現時根據{{!hasUserInfo}}的真值來判斷,這個值可以通過app.js是否獲取了資訊來賦值。
<block wx:if="{{!hasUserInfo}}"> <image class="userAvatar" src='../../images/icon/wechat.png'></image> <button open-type="getUserInfo" bindgetuserinfo="getUserInfo">微信授權登入</button> </block>
但是,可能出現使用者已經授權了,但是app.js獲取個人資訊時過慢,然而我們的授權按鈕卻錯誤的以為app.js沒有獲取到資訊,所以將授權按鈕渲染了出來。
這時,我們希望,在app.js判斷使用者已經授權且獲取到資訊後,告訴我們的授權按鈕。
我們在me.js中新增如下程式碼段。
onLoad: function() { // 獲取個人資訊 if(app.globalData.userInfo){ this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) }else{ // 在app.js沒有獲取到資訊時,判斷app.js的非同步操作是否返回資訊 app.userInfoReadyCallback = res => { this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } } }
為什麼這裡會有個app.userInfoReadyCallback函式呢,我們注意到在app.js的wx.getSetting裡有一段回撥函式,這個函式就是用來解決非同步的問題。