在我的项目中,用户一开始进入小程序的时候不要求马上登录。当用户进行商品收藏、购买或者进入个人中心的时候会弹窗要求用户登录。先看下效果:
取消之后可以切换别的页面之后再次进入个人中心,依然会出现弹窗提示。
这里呢,主要记录的是要把检测登录状态弹框提示的函数放在哪里才能完美实现:点击个人中心出现弹窗,取消之后再次进入个人中心还会出现弹窗。
像检测登录状态、实现登录功能等函数,是我之前已经写好的,这里只是记录具体如何在页面中使用而已 。可以看看我之前写的mpvue+vuex封装wx.request管理token。至于登录流程,由于微信小程序API改版之后没办法直接通过函数调用实现弹窗要求授权,必须引导用户去点击button后才能授权,这就需要我们设计新的登录流程啦。之后如果有空的话,我会写mpvue实现新登录流程的博客。
先回来看看上述效果是如何实现的。首先在个人中心选项卡对应的vue文件中:
一开始,我在onLoad函数中调用函数判断是否是登录状态的,如果用户选择的是一键登录,之后的流程就没有问题。但是如果用户选择了取消,之后切换别的页面然后再次进入个人中心,这个时候并没有出现该有的弹框提示。
这种情况跟页面的onLoad()的执行时间有关,小程序初始化完成后,在进入页面的时候会先执行页面加载onLoad(),再执行页面显示onShow(),当切换到别的页面,然后再次进入该页面时,onLoad()不会再执行,而是再次执行onShow(),也就是说每次进入页面,一定会执行的是onShow()。可以把判断登录状态的函数放在onShow()中:
// 每次进入页面都会执行
onShow () {
this.initData()
this.initPageStyle()
}
这一步完成之后,正常登录之后会显示正常的个人中心页面,但是会发现有时候其他地方显示了,用户的微信名称、昵称没有显示。在项目中,授权登录时获取了用户信息存入缓存,在页面判断完登录状态后,页面会从缓存取微信头像,微信名称作显示。由于登录操作是异步的,可能还没把用户信息写入缓存,页面就开始在缓存中获取用户信息,导致页面中用户的微信名称、昵称无法显示。这个时候可以使用async await:
async initData () {
// 等待登录函数调用完毕后再执行下一步
await this.$login.isLogin()
this.userInfo = wx.getStorageSync('userInfo')
this.userPageData = sysData.userPageData
},
以下为个人中心页面全部代码:
<template>
<div class="wrapper" :style="[{minHeight: windowHeight+'px'},{minWidth: windowWidth+'px'}]">
<div v-if="isLogin" class="content">
<div class="header">
<div class="user">
<img :src='userInfo.avatarUrl'/>
<span>{{userInfo.nickName}}</span>
</div>
</div>
<div class="tab">
<tabCard :tabData = 'userPageData.firTabCard'></tabCard>
<tabCard :tabData = 'userPageData.secTabCard'></tabCard>
<infoCard :infoData = 'userPageData.infoCard'></infoCard>
</div>
</div>
<div v-else class="outline">请先登录</div>
</div>
</template>
<script>
import tabCard from '../../components/tabCard'
import infoCard from '../../components/infoCard'
import sysData from '../../utils/sysData'
export default {
data () {
return {
userInfo: {},
windowHeight: 0,
windowWidth: 0,
userPageData: {}
}
},
components: {
tabCard,
infoCard
},
computed: {
isLogin () {
return this.$store.getters.getLoginStatus
}
},
methods: {
async initData () {
// 等待登录函数调用完毕后再执行下一步
await this.$login.isLogin()
this.userInfo = wx.getStorageSync('userInfo')
this.userPageData = sysData.userPageData
},
initPageStyle () {
let that = this
wx.getSystemInfo({
success (res) {
that.windowHeight = res.windowHeight
that.windowWidth = res.windowWidth
}
})
}
},
// 每次进入页面都会执行
onShow () {
this.initData()
this.initPageStyle()
}
}
</script>
<style scoped lang="stylus" rel="stylesheet/stylus">
.wrapper
background-color: #85A5CC
.content
width: 100%
height: 100%
.header
width: 100%
height: 30%
color: #ffffff
display: flex;
flex-direction: column;
align-items: center;
padding: 30rpx 0 40rpx 0
.user
width: 95%
img
width: 116rpx
height: 116rpx
vertical-align: middle
border-radius: 50%
span
margin-left: 5%
vertical-align: middle
.tab
display: flex
flex-direction: column
align-items: center
.outline
position: absolute
top: 50%
left: 50%
transform: translate(-50%, -50%)
white-space: nowrap
</style>