文章目錄
一、用戶授權流程
1.用戶授權判斷
通過mpvue.getSetting判斷小程序是否獲得權限
新建src\api\wechat.js
export function getSetting(auth, onSuccess, onFail) {
mpvue.getSetting({
success(res) {
// authSetting: 用戶授權結果(是否包含對應權限)
if (res.authSetting[`scope.${auth}`]) {
onSuccess(res)
} else {
onFail(res)
}
},
fail(res) {
}
})
}
在src\pages\index\index.vue中檢驗授權
import {getSetting} from '../../api/wechat'
mounted() {
this.getSetting()
},
methods: {
getSetting() {
getSetting('userInfo', () => console.log('成功'), () => console.log('失敗'))
},
2.用戶申請授權
如果小程序未獲得授權,我們需要提供用戶主動申請授權的功能,微信規定獲取用戶信息,必須用戶主動觸發,此時我們需要藉助button組件完成用戶授權事件綁定,關鍵步驟:
- 新建src\components\base\Auth.vue:
<template>
<div class="auth-wrapper">
<div class="auth">
<div class="auth-info">
<div class="auth-img">
<ImageView src="https://www.youbaobao.xyz/mpvue-res/logo.jpg" round/>
</div>
<div class="sub-title">登錄小慕讀書</div>
<div class="title">全球好書免費讀</div>
</div>
<button
class="auth-btn"
@getuserinfo="getUserInfo"
open-type="getUserInfo">
授權登錄
</button>
</div>
</div>
</template>
<script>
import ImageView from './ImageView'
export default {
components: {ImageView},
methods: {
getUserInfo() {
this.$emit('getUserInfo')
}
}
}
</script>
<style lang="scss" scoped>
.auth-wrapper {
position: fixed;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background: #999999;
z-index: 1000;
.auth {
position: relative;
width: 270px;
height: 248px;
background: #f5f5f5;
border-radius: 18px;
.auth-info {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 22.5px;
.auth-img {
width: 74px;
}
.sub-title {
font-size: 13px;
color: #999999;
line-height: 18.5px;
margin-top: 18px;
}
.title {
font-size: 16px;
color: #333333;
font-weight: 400;
line-height: 22.5px;
margin-top: 3.5px;
}
}
.auth-btn {
position: absolute;
bottom: 0;
width: 100%;
height: 49px;
line-height: 49px;
font-size: 15px;
color: #FFFFFF;
background-image: linear-gradient(90deg, #1EA3F5 0%, #0F87FC 100%);
border-radius: 0 0 10px 10px;
}
}
}
</style>
注意@getuserinfo是小寫的。。。
- 在src\pages\index\index.vue中調用Auth組件,並修改dom結構爲如下:
<div>
<div class="home" v-if="isAuth">
<SearchBar />
<HomeCard/>
<HomeBannner/>
<div>
<HomeBook/>
<HomeBook/>
<HomeBook/>
<HomeBook/>
</div>
</div>
<Auth v-if="!isAuth"/>
</div>
....
import Auth from '../../components/base/Auth'
components: {....Auth},
data() {return {....isAuth: true}},
....
methods: {
getSetting() {
getSetting(
'userInfo',
() => {
console.log('成功')
this.isAuth = true
this.getUserInfo()
},
() => {
console.log('失敗')
this.isAuth = false
})
},
關於getuserinfo和open-type的官方說明如下:
屬性 | 說明 |
---|---|
open-type | 微信開放能力 |
bindgetuserinfo | 用戶點擊該按鈕時,會返回獲取到的用戶信息,回調的detail數據與wx.getUserInfo返回的一致,open-type="getUserInfo"時有效 |
查看官方文檔:授權 | 微信開放文檔
3.獲取用戶信息
通過mpvue.getUserInfo獲取用戶信息
- 在src\api\wechat.js中新增如下方法:
export function getUserInfo(onSuccess, onFail) {
mpvue.getUserInfo({
success(res) {
console.log('res')
const { userInfo } = res
if (userInfo) {
onSuccess(userInfo)
} else {
onFail(res)
}
},
fail(res) {
console.log('res') // 直接拋出異常
}
})
}
- 在src\pages\index\index.vue中新增如下方法:
getUserInfo() {
getUserInfo(
(userInfo) => {
console.log(userInfo)
},
() => {
console.log('獲取用戶信息failed...') // 獲取用戶信息,拋出異常
}
)
},
爲了使登錄過程更加合理,我們將初始化部分綜合到init()方法中:
mounted() {
this.init()
},
methods: {
init() {
this.getSetting()
this.getHomeData()
},
在src\api\wechat.js中新增如下兩個方法,用來緩存用戶授權信息:
export function setStorageSync(key, data) {
mpvue.setStorageSync(key, data)
}
export function getStorageSync(key) {
return mpvue.getStorageSync(key)
}
將setStorageSync和getStorageSync方法添加到getUserInfo的成功回調中:
getUserInfo() {
getUserInfo(
(userInfo) => {
console.log(userInfo)
setStorageSync('userInfo', userInfo)
const openId = getStorageSync('openId')
if (!openId || openId.length === 0) {
console.log('請求openId')
} else {
console.log('已獲得openId')
}
},
() => {
console.log('獲取用戶信息failed...') // 獲取用戶信息,拋出異常
}
)
},
4.獲取openId
由於每個用戶在每個小程序都會獲得唯一的openId,所以openId非常適合用作用戶的唯一標識,獲取openId我們需要通過官方提供的api auth.code2Session來獲取,爲了簡化api調用,課程提供了該api的封裝版本:API | 「小慕讀書」官網
打開小程序管理平臺:https://mp.weixin.qq.com/,登錄並找到APP_ID和APP_SECRET添加到src\utils\const.js中:
export const APP_ID = 'wx6ca257b141a31ade'
export const APP_SECRET = 'a32f84636cfcdba9688f928da3e2cbb4'
在src\api\index.js中添加getOpenId方法來調用wx.login接口:
import { APP_ID, APP_SECRET } from '../utils/const'
export function getOpenId(code) {
return get(`${API_URL}/openId/get`, {
appId: APP_ID,
secret: APP_SECRET,
code
})
}
在src\api\wechat.js中添加getUserOpenId方法,調用getOpenId方法
export function getUserOpenId(callback) {
mpvue.login({
success(res) {
if (res.code) {
const {code} = res
// console.log('code' + code)
getOpenId(code).then(response => {
// console.log(response)
const { data: { data: { openid } } } = response
setStorageSync('openId', openid)
callback && callback(openid)
// console.log('openid:' + openid)
}).catch(err => {
console.log(err) // 直接拋出異常
})
} else {
console.log(res) // 直接拋出異常
}
},
fail(res) {
console.log(res) // 直接拋出異常
}
})
}
- 請求回來的response:
調試查看結果
- 清除緩存
- 重新運行小程序
- 授權登錄
- 確定
可見控制檯信息爲如下:
- 再次重新運行小程序:
這時使用的openId是緩存當中的
代碼中的APP_ID和APP_SECRET均爲註冊小程序時獲取到的,對應自己的小程序(與開發者綁定)詳細請看:查看微信公衆號的AppID和AppSecret
這裏推薦一個官方提供的工具:微信公衆平臺接口調試工具
5.用戶登錄
通過mpvue.login進行用戶登錄,登錄後會獲得code,該code可用於獲取openId,但要注意code只能使用一次,用完即作廢
6.用戶註冊
使用回調函數
現在既然已經有了openId,就可以在src\pages\index\index.vue中的getHomeData方法傳入這個openId:
getHomeData(openId) {
getHomeData({openId}).then(response => {...})
...
},
接下來在src\pages\index\index.vue中的getUserInfo方法中定義一個變量onOpenIdComplete,將它傳入getUserOpenId以實現動態獲取openId:
getUserInfo() {
const onOpenIdComplete = (openId) => {
this.getHomeData(openId)
}
getUserInfo(
(userInfo) => {
// console.log(userInfo)
setStorageSync('userInfo', userInfo)
const openId = getStorageSync('openId')
if (!openId || openId.length === 0) {
getUserOpenId(onOpenIdComplete)
console.log('請求openId')
} else {
console.log('已獲得openId')
onOpenIdComplete(openId)
}
},
() => {
console.log('獲取用戶信息failed...') // 獲取用戶信息,拋出異常
}
)
},
這裏需要梳理一下里面這個回調:
- 點擊授權登錄
- 調用index.vue裏的getUserInfo方法
- 執行src\api\wechat.js的getUserInfo方法
- 執行:getUserOpenId():授權登錄後拿到openId傳給回調函數callback
- 執行回調方法onOpenIdComplete(作爲參數callback即回調函數)
- 帶着openId去執行index.vue裏的getHomeData,over
- 再次刷新
- 執行:else裏面的onOpenIdComplete(openId),(直接拿到緩存裏的openId)
- 帶着openId去執行index.vue裏的getHomeData,over
註冊
獲得openId後,我們可以通過該openId和用戶信息在小慕讀書中進行註冊,課程提供了註冊的api,立即查看:API | 「小慕讀書」官網
- 在src\api\index.js中添加register方法來調用wx.login接口:
export function register(openId, userInfo) {
return post(`${API_URL}/user/register`, {
openId,
platform: mpvuePlatform, // 通過這個參數獲取當前環境的platform(微信、支付寶、...)
...userInfo // 將userInfo數據打散傳入
})
}
- 然後在src\pages\index\index.vue中的回調函數onOpenIdComplete中調用註冊(這裏需要給onOpenIdComplete再加一個參數userInfo,注意改動的地方)
getUserInfo() {
const onOpenIdComplete = (openId, userInfo) => {
this.getHomeData(openId, userInfo)
register(openId, userInfo)
}
getUserInfo(
(userInfo) => {
// console.log(userInfo)
setStorageSync('userInfo', userInfo)
const openId = getStorageSync('openId')
if (!openId || openId.length === 0) {
console.log('請求openId')
getUserOpenId(openId => onOpenIdComplete(openId, userInfo))
} else {
console.log('已獲得openId')
onOpenIdComplete(openId, userInfo)
}
},
() => {
console.log('獲取用戶信息failed...') // 獲取用戶信息,拋出異常
}
)
},
- 這是運行小程序就會在控制檯看到如下信息(授權登錄和二次登錄截圖)
改造HomeCard中頭像和暱稱的數據源
- 刪掉src\pages\index\index.vue的getHomeData方法裏userInfo的模擬數據,改造之後如下:
this.homeCard = {
bookList: shelf,
num: shelfCount,
userInfo
}
- 爲getHomeData多傳一個參數userInfo,調用的地方也是如此
- 修改src\components\home\HomeCard.vue中數據源名稱與接口傳回的一致:
computed: {
avatar() {
return (this.data && this.data.userInfo && this.data.userInfo.avatarUrl) || ''
},
nickname() {
return (this.data && this.data.userInfo && this.data.userInfo.nickName) || ''
},
解決頭像加載前佔位圖拉伸:
- 修改src\components\home\HomeCard.vue中ImageView標籤的參數爲:
<ImageView
:src="avatar"
round
height="100%"
mode="scaleToFill"/>
- 修改src\components\base\ImageView.vue渲染層的根標籤:
<div class="image-view" @click="onClick" :style="{ height }">
- 授權組件中頭像也是相同的問題,修改如下:
src\components\base\Auth.vue
<ImageView
src="https://www.youbaobao.xyz/mpvue-res/logo.jpg"
round
height="100%"
mode="scaleToFill"/>
樣式中添加高度(受scaleToFill影響,否則高度爲0)
.auth-img {
width: 74px;
height: 74px;
}
這樣就一切正常了!
拓展:
二、授權組件
用戶授權登錄組件
組件名稱 | 屬性 | 參數 | 用途 | 默認值 |
---|---|---|---|---|
Auth | method | getUserInfo | 獲取用戶信息 | (空) |
三、做些優化
顯示加載樣式
在src\api\wechat.js中新增兩個方法:
export function showLoading(title) {
mpvue.showLoading({
title,
mask: true
})
}
export function hideLoading() {
mpvue.hideLoading({)
}
這裏是使用了微信自帶的兩個API:
使用樣式
- 加載中樣式在獲取授權之後加載數據完成之前之前調用:
getSetting() {
getSetting(
'userInfo',
() => {
console.log('授權成功')
this.isAuth = true
this.getUserInfo()
showLoading('正在加載')
},
() => {
console.log('授權失敗')
this.isAuth = false
})
},
- 隱藏加載在加載頁面數據完成後和數據加載失敗時調用:
getHomeData(openId, userInfo) {
getHomeData({openId}).then(response => {
...
hideLoading()
}).catch(() => {
hideLoading()
})
},