【笔记】实战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

组件名称属性参数用途默认值
AuthmethodgetUserInfo获取用户信息(空)

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()
  })
},
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序边界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值