I 效果:每个需要判断登录的页面只需引入该组件,即可知道显示登录按钮还是页面信息。
注意:这里不是登录页面,只是写的一个按钮组件,通过判断显示和隐藏按钮。
流程图如下
效果图如下
登录过程
html代码
小程序授权登录主要通过button按钮绑定bindgetuserinfo方法实现。我们这边把登录按钮封装成了组件,通过isShowLogin
变量控制按钮显示隐藏。
css代码
.login-box {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 9999;
background: white;
display: flex;
flex-direction: column;
justify-content: center;
}
.login-btn {
text-align: center;
font-size: 0.875rem;
width: 90%;
border-radius: 20rpx;
height: 100rpx;
line-height: 100rpx;
background: #fcea5e;
color: black;
margin-bottom: 50rpx;
}
.login-btn::after {
border: none !important;
}
js代码
组件data中定义显示、隐藏组件的变量
data: {
isShowLogin: false
},
在自定义组件的attached
(这里注意不要使用created
,在created
中访问不到setData
)生命周期函数中判断用户当前是否是登录状态,如果是未登录状态,则调用wx.longin({})
方法,在成功的回调中请求获取sessionkey的接口。
- sessionkey的接口返回的是用户信息,则此用户为小程序的老用户,直接获取即将跳转的页面重定向到此页面;
- sessionkey的接口返回的是sessionkey的值,则继续请求微信登录的接口。
import LOGIN_BUTTON from '../../utils/login'
import LOGIN from '../../models/login'
import getPage from '../../utils/getPage'
attached() {
let user = wx.getStorageSync('user')
if (!user?.id) {
this.setData({ isShowLogin: true })
wx.setNavigationBarTitle({ title: '登录' })
wx.login({
success: e => {
let code = e.code
// LOGIN()是封装的请求接口的方法
LOGIN().fetchSessionkey({ code: code }).then(res => {
if (res.error == 0) {
if (res.data.id) {
wx.setStorageSync('user', res.data) // 将用户信息存储到缓存中
wx.setStorageSync('cookiekey', res.data.cookiekey)
getPage() // 重定向到用户想进入的页面,后面贴出代码
}
}
})
}
})
}
},
methods: {
getUserInfoTap(res) {
const { encryptedData, iv } = res.detail
if (!encryptedData || !iv) return // 如果用户点击了拒绝授权
let params = { encryptedData, iv }
LOGIN_BUTTON(params) // 因为判断登录的部分我们要复用,所以我这边写了个公用方法,将所需两个参数传进方法里即可(使用方法要引入哦!!)
}
}
LOGIN_BUTTON判断登录的方法
import LOGIN from '../models/login'
import getPage from '../utils/getPage'
export default function LOGIN_BUTTON(params) {
const data = {...params} // 接收传进的两个参数
wx.login({
success: e => {
let code = e.code
LOGIN().fetchSessionkey({ code: code }).then(res => { // 请求获取sessionkey方法(LOGIN()是封装好的类中的fetchSessionkey方法)
if (res.error == 0) {
if (res.data.id) {
data.cb&&data.cb() // 若获取到的是用户信息,则为老用户,直接授权登录,不需给用户展示登录按钮
} else {
let params = {
...data,
sessionkey : res.data.sessionkey
}
wx.login({
success: e => {
LOGIN().fetchWxLogin(params).then(res => { // 请求微信登录的接口
if (res.error == 0) {
wx.setStorageSync('user', res.data)
wx.setStorageSync('cookiekey', res.data.cookiekey)
getPage() // 重定向到当前页
}
})
},
fail: e => {
wx.showToast({
title: '登录失败,请重新登录',
icon: 'none'
})
}
})
}
} else {
wx.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch( err => {
wx.showToast({
title: err,
icon: 'none'
})
})
}
})
}
重定向页面的方法
export default function getPage() {
let pages = getCurrentPages()
let curPage = pages[pages.length - 1]
let url = `/${curPage.route}?`
for (let key in curPage.options) {
url += `${key}=${curPage.options[key]}&`
}
let tabRoutes = ['pages/my/my']
if (tabRoutes.includes(curPage.route)) {
wx.reLaunch({
url: '/pages/my/my',
})
} else {
wx.redirectTo(
{ url: url.substr(0, url.length - 1) }
)
}
}
登录状态还有失效的状态,即用户若是点击某一项操作按钮,接口返回失效状态码。
在app.js中定义一个全局变量,通过监听这个全局变量控制登录按钮显示与隐藏
globalData: {
userInfo: null,
loginFailure: false
},
loginFailureWatch (cb) {
var obj = this.globalData;
Object.defineProperty(obj, "loginFailure", {
configurable: true,
enumerable: true,
set (value) {
if (cb) cb(value);
}
})
}
在请求里将全局变量的值变为true
if (res.data.error == '9998') {
getApp().globalData.loginFailure = true
}
在自定义组件中attached方法中,改变显示按钮的变量值
getApp().loginFailureWatch(val => {
if (val) this.setData({ isShowLogin: true })
})