在我的項目中,用戶一開始進入小程序的時候不要求馬上登錄。當用戶進行商品收藏、購買或者進入個人中心的時候會彈窗要求用戶登錄。先看下效果:
取消之後可以切換別的頁面之後再次進入個人中心,依然會出現彈窗提示。
這裏呢,主要記錄的是要把檢測登錄狀態彈框提示的函數放在哪裏才能完美實現:點擊個人中心出現彈窗,取消之後再次進入個人中心還會出現彈窗。
像檢測登錄狀態、實現登錄功能等函數,是我之前已經寫好的,這裏只是記錄具體如何在頁面中使用而已 。可以看看我之前寫的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>