微信小程序用户信息逻辑大变,探索最优处理方案

242 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情

这里因为这个小程序只是一个简单的工具类小程序,不涉及用户管理一些信息所以直接用微信的授权登录即可。不过为了界面的美观性我还是加入了用户的昵称和头像,没想到啊,微信这个浓眉大眼的接口逻辑都给我变了,没办法在人家的场地只能自己解决了。

接上篇小程序入门——设计页面 - 掘金 (juejin.cn)

突闻噩耗

我本来信心满满的,毕竟这个功能我之前也实现过,这里不过是复用一遍而已。然而。突闻噩耗,# wx.getUserInfo经调整在今年已经不能用了,而我之前的小程序用的还是这个,迟钝的我还在纳闷今年怎么寒假社会活动报名的信息全是灰色头像。

image.png

0.gif

微信开发公众平台给了新的接口去获取用户的昵称和头像,但是我这类工具小程序就算了吧,这样搞用户体验得多差啊。我首先要考虑的还是用户体验问题。

之前放这个用户昵称也就是为了界面不那么单调而已。既然这样,为了我的界面的美观性,我目前想到的解决方案是直接把昵称写死成微信用户,然后再提供更改功能吧。

哎,又给我增加工作量。难蚌

1673431093333.png

说实话,我好想把这个我的界面干掉啊,但是我又需要这个页面里的客服功能来进行用户反馈。娘希匹,自己实现的界面跪着也要把它完善喽。经典为了瓶醋,买个大螃蟹。

1.实现逻辑

默认昵称直接微信用户,默认头像我选的是Vue默认的那个头像,很魔性的,我很喜欢。

在这里我梳理下逻辑:

  1. 首先用户初次登录我们要给他一个默认的头像,默认的昵称,并且在用户换头像和昵称的时候把这些信息存到缓存里面。
  2. 如果用户之前登录过,如果缓存里面有用户数据就默认他登录了,直接用缓存里面的用户头像和昵称。
  3. 所有用户在页面加载时就会用wx.login获取微信用户唯一的openid作为用户的唯一标识,并查询redis,或mysql以此来判定用户的等级。但是这个方案估计不会用,因为一个小程序,没必要这么复杂。后面再说我的解决方案。

2.具体实现

我是真没想到这点东西折腾了我半天。踩了不少坑,不过都是不值得记录的小问题。

  • mine.html主要改的是user-bar这部分。
    <view class="user-bar">
      <!-- <view class="avatar" wx:if="{{user.avatar}}">
        <image mode="scaleToFill" src="{{user.avatar}}"></image>
      </view> -->
      <button class="avatar" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
        <image class="avatar-img" src="{{user.avatar}}"></image>
      </button>
      <!-- <view class="avatar" wx:else bindtap="login">
        <open-data type="userAvatarUrl"></open-data>
      </view> -->

      <view class="detail">
        <!-- <view class="name">{{user.nickName}}</view> -->
        <input value="{{user.nickName}}" type="nickname" class="name" bindblur="getnickname" placeholder="请输入用户名" placeholder-class="placeholderClass"/>
        <view class="desc">
          <view wx:if="{{user.label==1}}" class="tag small round bg-skin1">普通用户</view>
          <view wx:if="{{user.label==2}}" class="tag small round bg-yellow">普通VIP</view>
          <view wx:if="{{user.label==3}}" class="tag small round bg-orange">超级VIP</view>
        </view>
      </view>

      <!-- <view class="detail" wx:else bindtap="login">
        <input type="nickname" class="name" placeholder="微信用户" placeholder-class="placeholderClass"/>
        <view class="desc">
          <view class="tag">
            登录立即解锁更多功能
          </view>
        </view>
      </view> -->
    </view>
  • index.js主要是对应了几个逻辑。

1. 首先加两个全局变量

const defaultAvatarUrl = 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif'
var userinfo={}

2. 然后是加载页面前判断缓存中有没有用户信息,如果没有的话初始化用户信息,如果有的话直接用缓存里的信息。

  onLoad(options) {
    var that = this
    wx.getStorage({
      key: 'userinfo',
      success(res) {
        userinfo=res.data
        that.setData({
          user: res.data
        })
        console.log("缓存中用户信息", userinfo)
      },
      fail(res) {
        console.log("缓存中无用户信息")
        userinfo.avatar = defaultAvatarUrl
        userinfo.nickName = "微信用户"
        userinfo.label = "1"
        console.log("初始化用户信息", userinfo)
        that.setData({
          user: userinfo
        })

      }
    })
  },

如果不太理解什么是生命周期onLoad,可以参考微信小程序的生命周期概览 - 掘金 (juejin.cn)里的页面生命周期部分。

3. 对应更改头像的部分

onChooseAvatar(e) {
    console.log("更换头像", e.detail.avatarUrl)
    let imgBase64 = wx.getFileSystemManager().readFileSync(e.detail.avatarUrl, 'base64');
    let avatar='data:image/png;base64,' + imgBase64
    //缓存更新头像
    userinfo.avatar = avatar
    wx.setStorage({
      key: "userinfo",
      data:userinfo
    })
    //页面展示更新头像
    this.setData({
      'user.avatar': avatar
    })
  },

这里为什么要转码成base64,可能很多人不理解。其实是因为我们用组件获取到的头像链接是临时的,甚至不能在前端页面展示出来,所以转成base64便于持久化存储。

4. 对应更改用户名的部分

getnickname(e) {
    if (this.data.user.nickName == e.detail.value) {
      console.log("未更换昵称")
    } else {
      console.log("更换昵称", e.detail.value)
      //缓存更新昵称
      userinfo.nickName = e.detail.value
      wx.setStorage({
        key: "userinfo",
        data:userinfo
      })
      //页面展示更新昵称
      this.setData({
        'user.nickName': e.detail.value
      })
    }
  },

这里如果你足够细心的话,会发现我用的是bindblur而不是bindinput或者bindconfirm。这里对比下三者的关系和这里的优劣。
-bindinput比较常用,但是在这里不太好用,主要是因为每打一个字都会触发一次这个函数,我觉得很不优雅。
-bindconfirm我经常用,只有在用户确定的时候才会触发这个函数,我觉得在这个很优雅,但是在这里不适用,主要因为下面的第二张图,我直接用自己的微信昵称时不会触发这个函数。
-bindblur我很少用,这个主要是焦点逻辑,就是你点到其他组件焦点从当前组件input转到其他组件就会触发。而这个触发经常容易误触,所以我做了个判断if (this.data.user.nickName == e.detail.value) { console.log("未更换昵称")}

不过写完对比后我发现,其实我的这个bindblur也不太优雅,可能还没有bindinput优雅。果然,还是得静下心来。

image.png

  • mine.wxss主要改的是以下几部分。
.container .user .user-bar .avatar {
  height: 130rpx;
  width: 130rpx;
  margin: 10rpx;
  border: 0rpx;
  padding-left: 0rpx;
  padding-right: 0rpx;
}
.container .user .user-bar .avatar .avatar-img{
  height: 130rpx;
  width: 130rpx;
}

.container .user .user-bar .detail {
  width: 400rpx;
  margin-left: 40rpx;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  color: #fff;
  box-sizing: border-box;
}

.container .user .user-bar .detail .name {
  height:auto;
  margin: 5rpx;
  font-size: 55rpx;
  font-weight: bold;
  color: #fff;
}

.placeholderClass{
	color: #fff;
}

.container .user .user-bar .detail .desc {
  margin-top: 15rpx;
  /* width:180rpx;    */
  /* font-weight: bold; */
  display: flex;
  justify-content: flex-start;
}
  • mine.json基本没有变动。

3.总结

这次微信公众平台这个接口的调整导致很多小程序的逻辑都要大改。我个人感觉是没啥必要的,平心而论,这个昵称和用户头像不是啥敏感信息,搞这么复杂干嘛?