开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情
这里因为这个小程序只是一个简单的工具类小程序,不涉及用户管理一些信息所以直接用微信的授权登录即可。不过为了界面的美观性我还是加入了用户的昵称和头像,没想到啊,微信这个浓眉大眼的接口逻辑都给我变了,没办法在人家的场地只能自己解决了。
接上篇小程序入门——设计页面 - 掘金 (juejin.cn)
突闻噩耗
我本来信心满满的,毕竟这个功能我之前也实现过,这里不过是复用一遍而已。然而。突闻噩耗,
# wx.getUserInfo经调整在今年已经不能用了,而我之前的小程序用的还是这个,迟钝的我还在纳闷今年怎么寒假社会活动报名的信息全是灰色头像。
微信开发公众平台给了新的接口去获取用户的昵称和头像,但是我这类工具小程序就算了吧,这样搞用户体验得多差啊。我首先要考虑的还是用户体验问题。
之前放这个用户昵称也就是为了界面不那么单调而已。既然这样,为了我的界面的美观性,我目前想到的解决方案是直接把昵称写死成微信用户,然后再提供更改功能吧。
哎,又给我增加工作量。难蚌
说实话,我好想把这个
我的界面干掉啊,但是我又需要这个页面里的客服功能来进行用户反馈。娘希匹,自己实现的界面跪着也要把它完善喽。经典为了瓶醋,买个大螃蟹。
1.实现逻辑
默认昵称直接微信用户,默认头像我选的是Vue默认的那个头像,很魔性的,我很喜欢。
在这里我梳理下逻辑:
- 首先用户初次登录我们要给他一个默认的头像,默认的昵称,并且在用户换头像和昵称的时候把这些信息存到缓存里面。
- 如果用户之前登录过,如果缓存里面有用户数据就默认他登录了,直接用缓存里面的用户头像和昵称。
- 所有用户在页面加载时就会用
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优雅。果然,还是得静下心来。
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.总结
这次微信公众平台这个接口的调整导致很多小程序的逻辑都要大改。我个人感觉是没啥必要的,平心而论,这个昵称和用户头像不是啥敏感信息,搞这么复杂干嘛?