微信小程序基于云数据库实现点赞功能

微信小程序基于云数据库实现点赞功能

微信小程序基于云数据库实现点赞功能

  • 首先你要开通云开发,然后点击数据库创建集合(这里我的集合是‘Books’),然后在集合里面添加数据,注意将集合对应的权限改为“自定义安全规则”
    在这里插入图片描述

  • 将安全规则自定义为“所有用户可读写”
    在这里插入图片描述

  • 思路如下:

  1. 利用云函数获取用户的openid
  2. 从数据库获取需要的like,like_num,like_people(放对应书籍id的点赞用户的openid)等数据,放入新建newList的数组中
  3. 在newList的like_people这个二维数组中遍历当前用户openid是否出现过,出现过则把该用户点赞过的书籍id放入新建iszan数组中
  4. 寻找iszan数组和newList数组中相同的id(我用的方法时间复杂度都是O(n²),有更好方法欢迎指导),有相同的则“点亮红心”
  5. 点赞事件:只需一个判断条件——①iszan数组中是否包含该书籍id或者②该书籍的like_people数组是否包含该用户openid,如果是的话就“取消点赞”,否则“点赞”
  6. 和后台交互,后台数据要同步,使用update

代码:

wxml

 <block wx:for='{{newsList}}' wx:key="index">
  <view class='item-zan' bindtap='thumbsup' data-id='{{item._id}}'>
    <image src='/images/like.png' style="width:60rpx;height:60rpx" wx:if="{{!item.like}}"></image><!--未点赞-->
    <image src='/images/like_active.png' style="width:60rpx;height:60rpx" wx:else></image><!--点赞-->
    <view style="margin-left:20rpx">{{item.like_num}}</view>
  </view>
</block>

通过thumbsup事件完成点赞,把其中的like由false改为true(取消点赞则是相反)来显示

js

const db = wx.cloud.database()
const _ = db.command
const booksCollection = db.collection('Books')
Page({

  data: {
    newsList: [], //列表数据
    iszan: [], //点过赞的id集合
    like_people: [], //每个列表数据的点赞的用户集合
    openid: ''
  },

  //页面加载初始化列表数据
  onLoad: function () {
    let that = this;
    wx.cloud.callFunction({
      name: 'getOpenid',
      complete: res => { // 获取用户openid
        console.log('云函数获取到的openid: ', res.result.openid)
        that.setData({
          openid: res.result.openid
        })
        booksCollection.field({ //发送请求获取列表数据
          _id: true,
          like: true,
          like_num: true,
          like_people: true
        }).get({
          success: res => {
            that.setData({
              newsList: res.data
            })
            var iszan = that.data.iszan;
            for (var i = 0; i < res.data.length; i++) { //数据获取成功后,进行遍历,拿到所有已经点过赞的书籍id
              for (let j = 0; j < res.data[i].like_people.length; j++) {
                if (res.data[i].like_people[j] == that.data.openid) { 
                  iszan.push(res.data[i]._id) //根据改用户的数据找到已经点赞的,把书籍id放入新建数组中
                }
              }
            }
            for (let i = 0; i < res.data.length; i++) {
              res.data[i].like = false
              for (let j = 0; j < iszan.length; j++) { //利用新建的iszan数组与list数组的id查找相同的书籍id
                if (res.data[i]._id == iszan[j]) { //双重循环遍历,有相同的id则点亮红心
                  res.data[i].like = true
                }
              }
            }
            console.log(res.data)
            that.setData({
              iszan: this.data.iszan,
              newsList: res.data
            })
            wx.setStorageSync('zan', iszan);
          }
        })
      }
    })
  },

  // 点赞函数  获取对应id
  thumbsup: function (e) {
    var shareid = e.currentTarget.dataset.id;
    this.zan(shareid);
  },

  //点赞处理函数    
  zan: function (item_id) {
    var that = this;
    var cookie_id = wx.getStorageSync('zan') || []; //获取全部点赞的id
    var openid = that.data.openid
    console.log(openid)
    for (var i = 0; i < that.data.newsList.length; i++) {
      if (that.data.newsList[i]._id == item_id) { //数据列表中找到对应的id
        var num = that.data.newsList[i].like_num; //当前点赞数
        if (cookie_id.includes(item_id) ) { //已经点过赞了,取消点赞
          for (var j in cookie_id) {
            if (cookie_id[j] == item_id) {
              cookie_id.splice(j, 1); //删除取消点赞的id
            }
          }
          --num; //点赞数减1
          that.setData({
            [`newsList[${i}].like_num`]: num, //es6模板语法,常规写法报错
            [`newsList[${i}.].like`]: false //我的数据中like为'false'是未点赞
          })
          wx.setStorageSync('zan', cookie_id);
          wx.showToast({
            title: "取消点赞",
            icon: 'none'
          })
          this.data.newsList[i].like_people.pop(openid)
        } else { //点赞操作
          ++num; //点赞数加1
          that.setData({
            [`newsList[${i}].like_num`]: num,
            [`newsList[${i}.].like`]: true
          })
          cookie_id.unshift(item_id); //新增赞的id
          wx.setStorageSync('zan', cookie_id);
          wx.showToast({
            title: "点赞成功",
            icon: 'none'
          })
          this.data.newsList[i].like_people.push(openid)
        }
        //和后台交互,后台数据要同步
        booksCollection.doc(item_id).update({
          data: {
            like: this.data.newsList[i].like,
            like_num: num,
            like_people: this.data.newsList[i].like_people
          },
          success: res => {
            console.log(res)
          }
        })
      }
    }
  }
})

小Tips


2022.04.27 更新

这是以前菜鸡的我写的,现在抛开这篇文章来看这个需求,最好的实现方式是:

  1. 每个用户维护一个数组A,数组A的元素是书籍列表中已点赞的书籍的索引(数组下标);
  2. 拉取书籍列表后,前端根据数组A来判断每本书籍该用户是否点赞过。

思维导图如下:
在这里插入图片描述

之前的代码我就不删掉了,按照这个新思路欢迎大家自行重构代码

  • 4
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值