最近在做一个简单的发帖小程序,涉及到点赞功能,起初以为很简单,后面才发现难点在于如何记录用户对该文章的点赞状态,避免下次打开点赞状态失效。先来看效果图:
经过百度半小时,发现可以用到小程序的缓存来解决这个问题,新建一个缓存对象 likeCollection
// 先从本地缓存中获取该对象,如果没有就新建一个空对象给它(说明用户是首次进入小程序)
let likeCollection = wx.getStorageSync('likeCollection');
if(!likeCollection){
wx.setStorageSync('likeCollection', {})
}
从后台获取文章对象数组,赋给变量list
// 小程序data属性
data:{
list:[]
}
// 调用云函数
wx.cloud.callFunction({
name:'getLists',
}).then(res=>{
this.setData({
list:res.result.data; // 赋值给list
})
}).catch(reason=>{console.log(reason)});
这里我们给获取到的list每个元素对象都添加一个属性 :“hasChange”,注意,类型是boolean,后台给的数据是没有这个属性的,值从likeCollection中获取,键是根据文章对象的属性 _id来区分,我这里后台使用的云开发,云数据库默认给每个记录提供一个 _id作为唯一标识符,也即关系数据库中的主键,这条语句要写在 onload() 函数里面,页面加载时就执行。
// list是从后台发过来的文章对象数组,这里不具体描述```
this.data.list.forEach((item)=>{
item['hasChange']=likeCollection[item._id];
})
这里的关键就在于,如果之前点过赞,likeCollection里的相应文章缓存值为true,如果未过赞,给list赋值为undefined,取消了点赞,值就变为fasle,在JS中,undefined == false
小程序页面上用 “hasChange” 这个属性来判断是否点过赞,显示对应的图片和数字:
<image src='{{item.hasChange?favor_img:favor}}' class='like' bindtap='praiseThis'
从上面代码可以看到,每个点赞图片绑定了一个单击事件 bindtap=‘praiseThis’,这个事件方法是关键所在,下面看代码
// 点赞函数
praiseThis(e){
var that = this;
let list = e.currentTarget.dataset.list;
let index = e.currentTarget.dataset.index;
let _id = e.currentTarget.dataset._id;
let hasChange = !(this.data[list][index].hasChange);
// 当前点击的赞的情况取反
console.log('当前点击的赞'+hasChange)
// 判断本地用户是否点赞了该文章
wx.getStorage({
key: 'likeCollection',
success:(res)=>{
let details = res.data;
console.log('缓存里的值:'+details[_id])
var onum = parseInt(that.data[list][index].clickload);
if(details[_id]){ // 如果点赞过,再点就是取消点赞
that.data['list'][index].clickload = (onum - 1);
that.data['list'][index].hasChange = false;
}
else {
// 未点赞,点赞量加一
that.data['list'][index].clickload = (onum + 1);
that.data['list'][index].hasChange = true;
}
// 然乎给缓存对象likeCollection添加/修改对应文章建的值,保存状态
wx.getStorage({
key: 'likeCollection',
success:datas=>{
let obj = datas.data;
obj[_id] = that.data['list'][index].hasChange
wx.setStorage({
data: obj,
key: 'likeCollection',
success:res=>{
console.log('缓存成功')
},
fail:reason=>console.log(reason)
})
}
})
this.setData({
list: that.data.list,
})
//调用云函数,实现后台的文章点击量的增减
wx.cloud.callFunction({
name:'pariseThis',
data:{
_id:_id, //文章id
likeOr:that.data[list][index].hasChange,
}
}).then(res=>{
console.log(res.result)
// 动态更新赞量
}).catch(reason=>{
console.log(reason)
});
}
})
},
下面看点赞时,缓存对象likeCollection中键值的变化:
首次进入,每个文章都是未点赞状态,此时缓存对象likeCollection为一个空对象:
下面,我们来给两篇文章点了赞,此时likeCollection的值已经改变:
可以看到,里面插入了两条主要以文章 _id为键名的数据,值为 true,下面取消一个赞:
再重新点赞,并且取消另一个赞:
好了,到这里,简单的点赞功能就基本实现了。
总结一下,就是从后台获取到文章数据后,从缓存对象likeCollection中根据文章_id查询点赞状态,未点过赞时,对象里的_id属性为undefined,取消后为false,点赞后为true;页面加载时将缓存中存储的状态赋值给对应文章的自定义属性 “hasChange”