【筆記】實戰mpvue2.0多端小程序框架——用戶授權


用戶授權 | 「小慕讀書」官網


一、用戶授權流程

auth

1.用戶授權判斷

通過mpvue.getSetting判斷小程序是否獲得權限

查看官方文檔:wx.getSetting(Object object) | 微信開放文檔

新建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獲取用戶信息

查看官方文檔wx.getUserInfo(Object object) | 微信開放文檔

  • 在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 | 「小慕讀書」官網

查看官方文檔auth.code2Session | 微信開放文檔

打開小程序管理平臺: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只能使用一次,用完即作廢

查看官方文檔:wx.login(Object object) | 微信開放文檔

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;
}

這樣就一切正常了!

拓展:

二、授權組件

用戶授權登錄組件
component_auth

組件名稱 屬性 參數 用途 默認值
Auth method getUserInfo 獲取用戶信息 (空)

LOGO圖片地址:https://www.youbaobao.xyz/mpvue-res/logo.jpg

三、做些優化

顯示加載樣式

在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()
  })
},
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章