微信小程序实现评论多级展开收起以及点赞功能

我们先来看看效果

所有效果均已实现,可以自己写写体验一下

接下来看看看代码

wxml

<!--pages/commodity/commodity-write-back/index.wxml-->
<view class="possess-layout margin-layout">
  <view class="main">
    <view class="commodity">
      <view class="commdoity-image">
        <image class="commodity-img" src="../../../img/shangpin.jpg"></image>
      </view>
      <view class="commodity-title">
        <view class="title commodity-line">华为旗舰5G手机拍照手机4GB+64GB魅蓝全网通华为旗舰5G手机拍照手机4GB+64GB魅蓝全网通华为旗舰5G手机拍照手机4GB+64GB魅蓝全网通</view>
        <view class="goods-price">
          <text>¥</text>
          <text>1888</text>
          <text>.</text>
          <text>66</text>
        </view>
      </view>
      <view class="commdoity-image-right">
        <image src="../../../img/icon/icon-evaluate-detail-gou.png"></image>
      </view>
    </view>
  </view>
</view>

<view class="appraise-user">
  <view class="possess-layout margin-layouts">
    <view class="main">
      <block wx:for="{{repotList}}" wx:key="key">
        <view class="user-comment">
          <view class="comment-user">
            <view class="user">
              <image class="user-head-portrait" src="{{item.img}}"></image>
              <view class="user-name">
                <view>{{item.users}}</view>
                <view>
                  <block wx:for="{{userpingfen}}" wx:key="index">
                    <block wx:for="{{item.pingfenpic}}" wx:key="index">
                      <image src="{{item}}"></image>
                    </block>
                  </block>
                </view>
              </view>
            </view>
            <view class="appraise-date">{{item.time}}</view>
          </view>
          <view class="appraise-contents">
            
          </view>
          <view class="appraise-content">
            <block wx:for="{{item.select}}" wx:key="index" wx:if="{{item.select.length != 0}}">
              <block wx:if="{{item.whether != ''}}"><view><text>是否正品:</text><text>{{item.whether}}</text></view></block>
              <block wx:if="{{item.colour != ''}}"><view><text>产品颜色:</text><text>{{item.colour}}</text></view></block>
              <block wx:if="{{item.effect != ''}}"><view><text>显色效果:</text><text>{{item.effect}}</text></view></block>
              <block wx:if="{{item.rests != ''}}"><view><text>其他特色:</text><text>{{item.rests}}</text></view></block>
            </block>
            <block wx:if="{{item.comment != ''}}"><text class="evaluate-content">{{item.comment}}</text></block>
          </view>
          <scroll-view scroll-x="true" class="scroll-view-true">
            <block wx:for="{{item.picture}}" wx:key="index">
              <image src="{{item}}"></image>
            </block>
          </scroll-view>
          <view class="appraise-base">
            <view class="have-bought">{{item.selected}}</view>
            <view class="write-back">
              <view catchtap="writeBack">
                <image class="wrte-back-img" src="../../../img/icon/icon-write-back.png"></image>
                <view>2</view>
              </view>
              <view>
                <image class="wrte-back-img" src="{{item.change? '../../../img/icon/icon-give-a-like-red.png': '../../../img/icon/icon-give-a-like.png'}}" data-curindex="{{index}}" bindtap="praiseThis"></image>
                <view class="{{item.change? 'hover-active': ''}}">{{item.praise}}</view>
              </view>
            </view>
          </view>
        </view>
      </block>
    </view>
  </view>
</view>
<!-- 商品评价详情 E -->
<view class="appraise-user">
  <view class="possess-layout margin-layouts">
    <view class="main">
      <view class="appraise-detail-top">共{{appraiseList.length}}条评论</view>
      <block wx:for="{{appraiseList}}" wx:key="index1" wx:for-index="index1">
        <view>
          <view class="username-appraise-top">
            <view class="username">
              <image src="{{item.img}}"></image>
              <view>{{item.username}}</view>
            </view>
            <view>
              <image class="praise" src="{{item.change? '../../../img/icon/icon-give-a-like-red.png': '../../../img/icon/icon-give-a-like.png'}}" data-curindex="{{index1}}" bindtap="praiseThiss"></image>
              <view class="amount {{item.change? 'hover-active': ''}}">{{item.praise}}</view>
            </view>
          </view>
        </view> 
        <view class="appraise-content"><text>{{item.appraise_content}}</text><text>{{item.time}}</text></view>
        <view class="reply-username">
          <block wx:if="{{item.reply_list.length > 2}}">
            <view class="reply-usernames {{item.isOpen? 'reply-usernames-active': ''}}">
              <block wx:for="{{item.reply_list}}" wx:key="index2" wx:for-index="index2">
                <view class="username-appraise-tops">
                  <view class="username">
                    <image src="{{item.img}}"></image>
                    <view>{{item.nickname}}</view>
                  </view>
                  <view>
                    <image class="praise" src="{{item.changes? '../../../img/icon/icon-give-a-like-red.png': '../../../img/icon/icon-give-a-like.png'}}" data-curindex="{{index1}}" data-curindexs="{{index2}}" bindtap="praiseThisss"></image>
                    <view class="amount {{item.changes? 'hover-active': ''}}">{{item.praise}}</view>
                  </view>
                </view>
                <view class="appraise-content"><text>{{item.reply_content}}</text><text>{{item.time}}</text></view>
              </block>
            </view>
            <view class="unfold-btn" bindtap="chooseUnfold" hidden="{{item.isOpen}}" data-value="{{item.isOpen}}" data-key="appraiseList.[{{index1}}]">展开{{item.reply_list.length - 1}}条回复</view>
            <view class="unfold-btn" bindtap="chooseUnfold" hidden="{{!item.isOpen}}" data-value="{{item.isOpen}}" data-key="appraiseList.[{{index1}}]">收起{{item.reply_list.length - 1}}条回复</view>
          </block>
          <block wx:else>
            <block wx:for="{{item.reply_list}}" wx:key="index2" wx:for-index="index2">
              <view class="username-appraise-top">
                <view class="username">
                  <image src="{{item.img}}"></image>
                  <view>{{item.nickname}}</view>
                </view>
                <view>
                  <image class="praise" src="{{item.changes? '../../../img/icon/icon-give-a-like-red.png': '../../../img/icon/icon-give-a-like.png'}}" data-curindex="{{index1}}" data-curindexs="{{index2}}" bindtap="praiseThisss"></image>
                  <view class="amount {{item.changes? 'hover-active': ''}}">{{item.praise}}</view>
                </view>
              </view>
              <view class="appraise-content"><text>{{item.reply_content}}</text><text>{{item.time}}</text></view>
            </block>
          </block>
        </view>
      </block>
    </view>
  </view>
</view>

<view class="end">
  - 这里就到底了哦 -
</view>

<!-- 底部评论 S -->
<view class="appraise-btn">
  <view class="appraise-btn-left">
    <image src="../../../img/icon/icon-import.png"></image>
    <view>说点什么吧</view>
  </view>
  <view class="appraise-btn-right">评价</view>
</view>
<!-- 底部评论 E -->

核心代码js

// pages/commodity/commodity-write-back/index.js
var pingxin = require("../../../utils/pingxing.js")
Page({

  /**
   * 页面的初始数据
   */
  data: {
    status: true, //评价框显示隐藏
    content: "",
    repotList: [
      {
        users: "山河",
        img: "../../../img/00.jpg",
        selected: "黑色#眼线笔01",
        select: [],
        praise: 0,
        change: false,
        comment: "颜值超高的一款眉笔!!!自然生动, 十分适合初学者~",
        picture: [
          "../../../img/00.jpg",
          "../../../img/00.jpg",
          "../../../img/00.jpg",
          "../../../img/00.jpg",
          "../../../img/00.jpg"
        ],
        time: "2020-05-29"
      },
    ],
    appraiseList: [
      {
        username: "太白子",
        img: "../../../img/00.jpg",
        is_merchant: 0,
        isOpen: false,
        change: false,
        praise: 0,
        appraise_content: "相信经常不化妆的小仙女都知道眉毛的重要性, 明人不说暗话,今天小编就来给推一推哪些优惠的眉笔吧!!!",
        reply_list: [
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, praise: 0, time: "05-25"},
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, praise: 0, time: "05-25" },
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, praise: 0, time: "05-25" },
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, praise: 0, time: "05-25" },
        ],
        time: "今天 15:07",
      },
      {
        username: "太白子",
        img: "../../../img/00.jpg",
        is_merchant: 1,
        isOpen: false,
        change: false,
        praise: 0,
        appraise_content: "相信经常不化妆的小仙女都知道眉毛的重要性, 明人不说暗话,今天小编就来给推一推哪些优惠的眉笔吧!!!",
        reply_list: [
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, time: "05-25", praise: 0, },
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, praise: 0, time: "05-25" },
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, praise: 0, time: "05-25" },
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, time: "05-25", praise: 0, },
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, praise: 0, time: "05-25" },
          { nickname: "太白金星", img: "../../../img/00.jpg", reply_content: "我也是这么觉得", changes: false, praise: 0, time: "05-25" }
        ],
        time: "今天 15:07",
      },
      
    ],
    userpingfen: [          // 用户评分
      { pingfen: 4 }
    ],

  },
  //失去焦点时获取里面评论内容
  bindTextAreaBlur: function (e) {
    this.setData({
      content: e.detail.value,
    })
  },
  //点击按钮时得到里面的值
  fabiao: function (e) {
    if(this.data.content == '') {
      wx.showToast({
        title: '内容不能为空',
        icon: "none",
        duration: 1500,
      })
    }else {
      this.setData({
        focus: 'false',
        concent1: this.data.content,
      })
      console.log(this.data.content)
    }
  },
  /**
   * 点击回复显示隐藏评价框
   */
  chengeStatusTop: function() {
    let status = this.data.status;
    this.setData({
      status: !status
    })
  },
  // 点赞功能逻辑
  praiseThis: function (e) {
    var index = e.currentTarget.dataset.curindex;
    if (this.data.repotList[index]) {
      var change = this.data.repotList[index].change;
      if (change !== undefined) {
        var num = this.data.repotList[index].praise;
        if (change) {
          this.data.repotList[index].praise = (num - 1);
          this.data.repotList[index].change = false;
        } else {
          this.data.repotList[index].praise = (num + 1);
          this.data.repotList[index].change = true;
        }
        this.setData({
          repotList: this.data.repotList
        })
      }
    }
  },
  // 点击展开
  chooseUnfold: function(e) {
    var key = e.currentTarget.dataset.key;
    var val = e.currentTarget.dataset.value;
    key = key + '.isOpen';
    this.setData({
      [key]: !val
    })
  },
  // 点赞功能逻辑s
  praiseThiss: function (e) {
    var index = e.currentTarget.dataset.curindex;
    if (this.data.appraiseList[index]) {
      var change = this.data.appraiseList[index].change;
      if (change !== undefined) {
        var num = this.data.appraiseList[index].praise;
        if (change) {
          this.data.appraiseList[index].praise = (num - 1);
          this.data.appraiseList[index].change = false;
        } else {
          this.data.appraiseList[index].praise = (num + 1);
          this.data.appraiseList[index].change = true;
        }
        this.setData({
          appraiseList: this.data.appraiseList
        })
      }
    }
  },
  // 点赞内层逻辑
  praiseThisss: function(e) {
    var index = e.currentTarget.dataset.curindex;
    var indexs = e.currentTarget.dataset.curindexs;
    console.log(indexs)
    if (this.data.appraiseList[index].reply_list[indexs]) {
      var change = this.data.appraiseList[index].reply_list[indexs].changes;
      if (change !== undefined) {
        var num = this.data.appraiseList[index].reply_list[indexs].praise;
        if (change) {
          this.data.appraiseList[index].reply_list[indexs].praise = (num - 1);
          this.data.appraiseList[index].reply_list[indexs].changes = false;
        } else {
          this.data.appraiseList[index].reply_list[indexs].praise = (num + 1);
          this.data.appraiseList[index].reply_list[indexs].changes = true;
        }
        this.setData({
          appraiseList: this.data.appraiseList
        })
      }
    }
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    var _this = this;
    var tiyan = this.data.userpingfen;
    for (var i = 0; i < tiyan.length; i++) {
      tiyan[i].pingfenpic = pingxin.pingfen(parseFloat(tiyan[i].pingfen));    //使用函数
    }
    _this.setData({
      userpingfen: tiyan
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {
    
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function() {

  }
})

wxss

/* pages/commodity/commodity-write-back/index.wxss */
.margin-layout {
  background: #FFFFFF;
  border-bottom-left-radius: 20rpx;
  border-bottom-right-radius: 20rpx;
}

.margin-layouts {
  border-radius: 20rpx;
  background: #FFFFFF;
  padding-bottom: 44rpx;
}
.comment-user {
  display: flex;
  justify-content: space-between;
  font-size: 25rpx;
  height: 100rpx;
}
.user {
  height: 100rpx;
  display: flex;
  align-self: center;
}
.user-head-portrait {
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  align-self: center;
  margin-right: 10rpx;
}
.user-name {
  align-self: center;
}
.appraise-date {
  align-self: center;
  color: #8a8a8a;
}
.commodity {
  width: 100%;
  height: 163rpx;
  font-size: 24rpx;
  display: flex;
  align-items: center;
  border-top: 1rpx solid #EEEEEE;
  margin-bottom: 20rpx;
}
.commdoity-image {
  width: 16.53%;
  display: flex;
}
.commodity-img {
  width: 124rpx;
  height: 124rpx;
  align-self: center;
}
.commodity-title .title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  text-overflow: ellipsis;
  overflow: hidden;
  align-self: center;
  margin-right: 20rpx; 
}
commdoity-image-right {
  width: 5.6%;
}
.commdoity-image-right image {
  width: 42rpx;
  height: 42rpx;
}
.commodity-line {
  -webkit-line-clamp: 2;
  opacity: 0.75;
}
.goods-price {
  margin-top: 34rpx;
  color: #F73A3F;
}
.goods-price text:nth-child(2), .goods-price text:nth-child(3) {
  font-size: 32rpx;
}
.goods-price text:nth-child(1), .goods-price text:nth-child(4) {
  font-size: 18rpx;
}
/* 用户评价内容 */
.appraise-user {
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
  overflow: hidden;
}
.user-comment {
  border-bottom: 1px solid #efefef;
}
.comment-user {
  display: flex;
  justify-content: space-between;
  font-size: 25rpx;
  height: 104rpx;
}

.user {
  height: 100rpx;
  display: flex;
  align-self: center;
}

.user-head-portrait {
  width: 64rpx;
  height: 64rpx;
  border-radius: 50%;
  align-self: center;
  margin-right: 10rpx;
}

.user-name {
  align-self: center;
  font-size: 20rpx;
}

.user-name view:nth-child(2) image {
  width: 14rpx;
  height: 14rpx;
}

.appraise-date {
  align-self: center;
  color: #666666;
  padding-top: 20rpx;
}

.appraise-content {
  font-size: 24rpx;
  margin: 0rpx 0 19rpx;
}
.appraise-content view {
  line-height: 36rpx;
}
.appraise-content view text:nth-child(1) {
  color: #999999;
}
appraise-content view text:nth-child(2) {
  color: #000000;
}

.evaluate-content {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  text-overflow: ellipsis;
  overflow: hidden;
  color: #000000;
}

.ellipsis {
  /* -webkit-line-clamp: 5; */
  opacity: 0.75;
}

.unellipsis {
  -webkit-line-clamp: 0;
  opacity: 1;
}

.content-jian {
  float: right;
}

.appraise-base {
  margin: 0 0 20rpx;
  display: flex;
  justify-content: space-between;
  font-size: 20rpx;
  height: 40rpx;
}

.scroll-view-true {
  width: 100%;
  display: flex;
  white-space: nowrap;
}
.scroll-view-true image {
  width: 230rpx;
  height: 240rpx;
  margin-right: 10rpx;
  padding-bottom: 11rpx;
}

.choice {
  color: #8a8a8a;
  align-self: center;
}

.write-back {
  display: flex;
  color: #666666;
  align-self: center;
}
.write-back view {
  display: flex;
  align-items: center;
}

.write-back view:nth-child(1){
  margin-right: 72rpx;
}

.write-back view:nth-child(1) image {
  width: 28rpx;
  height: 25rpx;
}

.write-back view:nth-child(2) image {
  width: 27rpx;
  height: 26rpx;
}
.hover-active {
  color: #F73C41;
}
.wrte-back-img {
  width: 28rpx;
  height: 28rpx;
  align-self: center;
  margin-right: 10rpx;
}

/* 评价 */
.appraise-detail-top {
  font-size: 24rpx;
  color: #333333;
  padding: 40rpx 0 0;
}
.username-appraise-top {
  display: flex;
  justify-content: space-between;
  margin-top: 32rpx;
}
.username-appraise-tops {
  display: flex;
  justify-content: space-between;
}
.username-appraise-top view:nth-child(2), .username-appraise-tops view:nth-child(2) {
  text-align: center;
}
.username-appraise-top .username, .username-appraise-tops .username {
  display: flex;
  font-size: 20rpx;
  color: #666666;
}
.username-appraise-top .username image, .username-appraise-tops .username image {
  width: 48rpx;
  height: 48rpx;
  border-radius: 50%;
  margin-right: 20rpx;
}
.username-appraise-top .praise, .username-appraise-tops .praise {
  width: 26rpx;
  height: 26rpx;
}
.amount {
  font-size: 20rpx;
  color: #999999;
}
.appraise-content {
  margin: -40rpx 68rpx 30rpx;
}
.appraise-content text:nth-child(1) {
  font-size: 20rpx;
  line-height: 30rpx;
  color: #000000;
  margin-right: 17rpx;
}
.appraise-content text:nth-child(2) {
  font-size: 20rpx;
  color: #999999;
}
.reply-username {
  margin: 0 0 0 68rpx;
}
.reply-usernames {
  height: 80rpx;
  overflow: hidden;
  margin: 0 0 0 68rpx;
}
.reply-usernames-active {
  height: 100% !important;
}
/* 展开btn */
.unfold-btn {
  margin: 0 0 0 68rpx;
  font-size: 24rpx;
  color: #FF888C;
  font-weight: Medium;
  font-family: "PingFang-SC-Medium";
}
/* 底部 */
.end {
  font-size: 20rpx;
  color: #999999;
  text-align: center;
  margin: 30rpx 0 151.3rpx;
}

.appraise-btn {
  height: 97.3rpx;
  background: #FFFFFF;
  position: fixed;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 21rpx;
}
.appraise-btn .appraise-btn-left {
  height: 64rpx;
  width: 620rpx;
  background: #EEEEEE;
  border-radius: 32rpx;
  margin-right: 26rpx;
  font-size: 24rpx;
  color: #999999;
  display: flex;
  align-items: center;
}
.appraise-btn .appraise-btn-left image {
  width: 29rpx;
  height: 22rpx;
  margin-left: 28rpx;
  margin-right: 9rpx;
}
.appraise-btn-right {
  font-size: 32rpx;
  color: #F73A3F;
}

创建pingxing.js文件

function pingfenxing(pingfen) {
  var _this = this,             // 这里的图片的路径, 自己需要修改
  data = {
    ling: "https://ico.dongtiyan.com/tu-125.png",
    zheng: "https://ico.dongtiyan.com/tu-123.png",
    ban: "https://ico.dongtiyan.com/tu-124.png",
  },
  nums =[];//这里是返回图片排列的顺序的数组, 这里要注意在页面使用的时候图片的路径,不过使用网络图片无所谓if((pingfen/0.2)%2==0){// 如果评分为正数,如4.0, 5.0}
  if((pingfen/0.2) % 2 == 0) {
    for (var i = 0; i < 5; i++) {
      if (i < pingfen) {
        nums.push(data.zheng);
      } else {
        nums.push(data.ling)
      }
    }
  } else { // 评分不为整数, 如3.5, 2.5
    for(var i=0; i<5; i++) {
      if(i<pingfen-0.5) {
        nums.push(data.zheng);        //先把证书分离出来,如: 3.5 这里就是先把3分离出来,把代表1的图片放进去
      } else if(i==(pingfen-0.5)) {
        nums.push(data.ban);        // 把小数的部分分离出来,如: 3.5里的0.5, 把代表0.5的图片放进去
      } else {
        nums.push(data.ling);   //然后剩下的就是没有满的用代表0的图片放进去,如: 3.5, 里面放进去了3个代表1的图片,然后放入了1个代表0.5的图片,最后还剩下一个图片的位置,这时候就放代表0的图片
      }
    }
  }
  return nums;
}
module.exports = {
  pingfen: pingfenxing
}

以上就是所有代码,以及效果

  • 11
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值