相信大家做小程序的乡话, 對(duì)微信登錄的機(jī)制都有一定的了解以及想法了摧玫;
大家八仙過海 各顯神通,下面這篇文章,只是我對(duì)其的了解
如果大家有好的想法 N芟瘛N萑骸!請(qǐng)一定 與 我交流;的印I瞩铩!
I降狠、處理登錄的邏輯
關(guān)于會(huì)遇到的問題以及處理
-
首先請(qǐng)求是個(gè)異步事件对竣,我們并不是所有接口都需要登錄;
既然是異步事件榜配, 那么我們肯定要在回調(diào)函數(shù)中進(jìn)行處理
這樣的話就要涉及到wx.request的封裝否纬;我們?cè)谙旅嬷v -
關(guān)于code的獲取
登錄需要用戶點(diǎn)擊微信自帶的button才能獲取到
<button class='login-btn' open-type="getUserInfo" bindgetuserinfo="getUserInfo"
type="warn" size="default" loading="{{loading}}" bindtap="primary">
一鍵登錄
</button>
關(guān)于權(quán)限判斷,以及如何判斷
咱們不能所有接口都需要登錄蛋褥, 那樣的話連審核都過不了临燃;
這里同樣需要對(duì)wx.requesrt進(jìn)行封裝;下面講-
登錄的處理邏輯圖:
II烙心、wx.request的封裝邏輯
1. wx.request的封裝
基礎(chǔ)層
a. 調(diào)用擴(kuò)展層的處理函數(shù)
b. wx.request請(qǐng)求擴(kuò)展層
beforeRequest 發(fā)起請(qǐng)求之前 處理有無網(wǎng)絡(luò)狀態(tài)
handleRequestInportData 處理請(qǐng)求參數(shù)
showMask 處理遮罩層
stopLoading 停止各種的loading
handleResponse 處理返回結(jié)果 (在這里面處理是否跳轉(zhuǎn)登錄)
2. wx.request的封裝邏輯圖
III膜廊、關(guān)于登錄 對(duì)wx.request的封裝
當(dāng)然是寫在handleResponse里面的
跟后端約定好返回碼 做對(duì)應(yīng)的操作;
我們這邊規(guī)定 如果返回 code == 401 || code == 403的話就表示沒有登錄
if (res.data.code == '401' || res.data.code == '403') {
console.error('沒登錄淫茵,去登錄溃论,并且設(shè)置狀態(tài)')
// 清空之前的token
wx.removeStorageSync('accessToken');
// 正在登錄中
if (that.globalData.isLogging) return true;
// 沒在登錄中 進(jìn)入登錄狀態(tài),并且設(shè)置isLogging
that.globalData.isLogging = true;
// 登錄失效且不在白名單
if (!CONFIG['API_WHITE_LIST'].includes(thisUrl)) {
// 跳到登錄
let pages = getCurrentPages();
for (let i in pages) {
if (pages[i].route == '/pages/login/login') {
// console.log(i)
wx.navigateBack({
delta: pages.length - (i + 1)
})
return true;
}
}
wx.navigateTo({ url: '/pages/login/login' });
return true;
}
return;
}
IV痘昌、相關(guān)代碼
1. wx.request關(guān)于基礎(chǔ)層的封裝
// 基礎(chǔ)層:
// 基于微信的request進(jìn)行二次封裝,myRequest是基礎(chǔ)層
// beforeRequest 處理有無網(wǎng)絡(luò)狀態(tài)
// handleRequestInportData 處理請(qǐng)求參數(shù)
// showMask 處理遮罩層
// stopLoading 停止各種的loading
// handleResponse 處理返回結(jié)果
myRequest: function (url, data, methods, callback, loadType, errorFun, headers) {
let _this = this;
// 檢查是擁有網(wǎng)絡(luò) 沒有網(wǎng)絡(luò) 就return炬转;
if (_this.beforeRequest(url)) return;
// 參數(shù)處理
let theData = this.handleRequestInportData(url, data, methods, callback, loadType, errorFun, headers, _this);
// 處理遮罩層
this.showMask(theData.loadType);
// 是否是啟用模擬數(shù)據(jù)
if (DEBUG) {
let responseData = myData.getData(url, data);
setTimeout(() => {
console.log('DEBUG response : ')
console.log(responseData.data)
_this.stopLoading();
callback(responseData)
// _this.handleResponse(responseData, theData);
}, 800)
}else{
// 開始請(qǐng)求
wx.request({
url: theData.url,
data: {
...theData.data,
..._this.globalData.otherParams
},
method: theData.methods,
header: theData.headers,
success: function (res) {
// 處理返回結(jié)果
_this.handleResponse(res, theData, _this, url);
},
fail: function (err) {
_this.stopLoading();
},
complete: function () {
}
})
}
// 請(qǐng)求結(jié)束
},
2. wx.request 擴(kuò)展層的封裝
// 在請(qǐng)求發(fā)起之前需要做的事情 處理有無網(wǎng)絡(luò)狀態(tài)
beforeRequest: function(tempUrl) {
let _this = this;
wx.getNetworkType({
success: function (res) {
if (res.networkType == 'none') {
return true;
}
}
})
},
// 處理請(qǐng)求參數(shù):
handleRequestInportData: (
url,
data,
methods = 'post',
callback = () => console.log('未傳入回調(diào)callback'),
loadType = 'mask',
errorFun = (err) => {
wx.hideLoading();
wx.showToast({
title: err.message,
icon: 'none',
mask: true,
duration: 2000
})
console.log('未傳入回調(diào) errorFun')
},
headers = {},
that
) => {
let requestData = {};
if (!url) {
console.error('傳入myRequest的URL不可為空');
return;
}
headers = {
'content-type': 'application/json',
'Authorization': 'Bearer ' + that.globalData.accessToken,
'enctype': 'raw'
}
data.referrer_uid = that.globalData.referrer_uid != 0 ? that.globalData.referrer_uid : 0;
requestData.url = InterFace[url];
requestData.data = data;
requestData.methods = methods;
requestData.callback = callback;
requestData.loadType = loadType;
requestData.errorFun = errorFun;
requestData.headers = headers;
return requestData;
},
// 處理返回結(jié)果:
handleResponse: (res, theData, that, tempUrl) => {
let _this = this;
that.stopLoading();
if (res.data.code == '401' || res.data.code == '403') {
console.error('沒登錄辆苔,去登錄,并且設(shè)置狀態(tài)')
// console.error(that.globalData.isLogging)
wx.removeStorageSync('accessToken');
// 正在登錄中 設(shè)置 isLogging
if (that.globalData.isLogging) return true;
that.globalData.isLogging = true;
// 登錄失效且不在白名單 !wx.getStorageSync('accessToken') && !API_WHITE_LIST.includes(tempUrl)
if (!CONFIG['API_WHITE_LIST'].includes(tempUrl)) {
// 跳到登錄
let pages = getCurrentPages();
// Tips: 判斷頁面棧中是否有l(wèi)ogin
for (let i in pages) {
if (pages[i].route == '/pages/login/login') {
wx.navigateBack({
delta: pages.length - (i + 1)
})
return true;
}
}
wx.navigateTo({ url: '/pages/login/login' });
return true;
}
return;
}
if (res.data.status == 200 && res.data.code != 0) {
// 調(diào)用錯(cuò)誤處理函數(shù)
theData.errorFun(res.data)
return;
} else if (res.data.code == '503' || res.data.code == '500') {
// 故障頁面
wx.reLaunch({
url: '/pages/error/error'
})
return;
}
// 正常情況下扼劈, 回調(diào)
if (res.data.status == 200 && res.data.code == 0) {
theData.callback(res.data);
return;
}
},
// 展示遮罩層:
showMask: (loadType) =>{
if(loadType == 'none') return;
if(loadType == 'top'){
wx.showNavigationBarLoading()
return;
}
wx.showLoading({
title: '加載中',
mask: true,
})
},
/*
* 停止各種loading狀態(tài)
* @function stopLoading
* @params {}
* @barth {Constantine, 2017-11-13 17:19:15}
*/
stopLoading: () => {
wx.hideLoading();
wx.hideNavigationBarLoading()
wx.stopPullDownRefresh()
},
3. 登錄頁面代碼
<!--pages/login/login.wxml-->
<nav title="選擇登錄方式"></nav>
<view class='cul-null'>抱歉您還未登錄呢, 請(qǐng)點(diǎn)擊下方授權(quán)按鈕登錄</view>
<view class='cul-null'>以使用更多功能</view>
<button class='login-btn' open-type="getUserInfo" bindgetuserinfo="getUserInfo" type="warn" size="default" loading="{{loading}}" bindtap="primary"> 一鍵登錄 </button>
<button class='login-btn' plain="{{true}}" type="default" size="default" bindtap="jumpTo" data-url='/pages/loginOld/loginOld'> 手機(jī)登錄 </button>
// pages/login/login.js
/**
* 生命周期函數(shù)--監(jiān)聽頁面隱藏
*/
onHide: function () {
app.globalData.isLogging = false;
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面卸載
*/
onUnload: function () {
app.globalData.isLogging = false;
},
// 發(fā)起登錄
getUserInfo: function (e) {
console.log(e)
this.setData({
loading: true
})
let encryptedData = e.detail.encryptedData;
let iv = e.detail.iv;
console.log('login in')
let _this = this;
wx.login({
success: ret => {
// 發(fā)送 res.code 到后臺(tái)換取 openId, sessionKey, unionId
var CODE = ret.code;
app.globalData.otherParams.wxcode = ret.code;
app.myRequest('login', {
wxcode: CODE,
info: e.detail.userInfo,
allInfo: e.detail,
},
'get',
function (data) {
console.log(data)
if(data.data.has_reg == false){
_this.userRegister(encryptedData, iv, data.data.openid)
console.error('沒有注冊(cè)過')
}else{
console.error('注冊(cè)過')
wx.showToast({
title: '已有賬號(hào),登錄中',
icon: 'none',
mask: true,
duration: 1500
})
_this.saveData(data);
_this.setData({
loading: false,
userInfo: data.data.memberProfile,
hasUserInfo: true
})
if (!data.data.has_phone){
// TODO: 判斷用戶有沒有手機(jī)號(hào)悬荣,沒有調(diào)用接口綁定入撒,并且完善密碼
}
setTimeout(() => {
wx.navigateBack({
delta: 1
})
}, 800)
}
})
console.log('login', ret)
}
})
},
// 自動(dòng)注冊(cè)
userRegister: function (encryptedData, iv, openid) {
let _this = this;
app.myRequest('userRegister', {
encryptedData: encryptedData,
iv: iv,
openid: openid
},
'post',
function (data) {
console.log(data)
// 緩存數(shù)據(jù)
_this.saveData(data);
_this.setData({
userInfo: data.data.memberProfile,
member: data.data.member,
hasUserInfo: true,
hideBindBlock: false,
loading: false
})
app.globalData.newUser = true;
wx.showToast({
title: '注冊(cè)成功',
icon: 'none',
mask: true,
duration: 1500
})
})
},
4.關(guān)于登錄按鈕的樣式
不滿意的話你可以讓微信自帶的buttom opacity = 0
然后自己寫一個(gè)想要的樣式放在自帶的buttom的下面
結(jié)束語
能堅(jiān)持到這里的已經(jīng)是真愛了
希望各位大神 有好的方法 與我交流??