这几天开发回复的功能以及点赞展示剩余评论,费劲脑汁的给弄出来了

样式

数据结构:只有两层 父评论和所有子评论
在这里插入图片描述
在这里插入图片描述

子评论代码

<template>
  <div>
    <view class="comment" v-for="info in commentChildren" :key="info.id">
      <div class="c-left">
        <image :src="info.avatar"></image>
      </div>

      <div class="c-right">
        <div class="c-name">
          {{ info.nickName }}
        </div>
        <div class="c-comment">{{ info.content }}</div>
        <div class="c-actions">
          <div class="c-time">{{ info.createTime }}</div>
          <div class="action-item">
            <image
              @click="btnPrarse(info)"
              :src="
                info.praise
                  ? '/static/index/like-done.png'
                  : '/static/index/like-icon.png'
              "
            ></image>
            {{ info.likesNumber }}
          </div>
          <div class="action-item">
            <image
              src="/static/index/comment-icon.png"
              @click="btnComment(info)"
            ></image>
            <text v-if="info.childrenCommentInfos.length">{{
              info.childrenCommentInfos.length
            }}</text>
            <text v-else>0</text>
          </div>
        </div>
        <div v-if="info.childrenCommentInfos.length > 0">
          <div v-if="info.contentAll">
            <view class="comment">
              <div class="c-left">
                <image :src="info.childrenCommentInfos[0].avatar"></image>
              </div>

              <div class="c-right">
                <div class="c-name">
                  {{ info.childrenCommentInfos[0].nickName }}
                  <div style="color: #333; margin-top: 10rpx">
                    回复
                    <text class="replyer"
                      >{{ info.childrenCommentInfos[0].beRepliedName }}:</text
                    >
                    <text class="c-comment">{{
                      info.childrenCommentInfos[0].content
                    }}</text>
                  </div>
                </div>
                <div class="c-actions">
                  <div class="c-time">
                    {{ info.childrenCommentInfos[0].createTime }}
                  </div>
                  <div class="action-item">
                    <image
                      @click="btnPrarse(info.childrenCommentInfos[0])"
                      :src="
                        children.praise
                          ? '/static/index/like-done.png'
                          : '/static/index/like-icon.png'
                      "
                    ></image>
                    {{ info.childrenCommentInfos[0].likesNumber }}
                  </div>
                  <div class="action-item">
                    <image
                      src="/static/index/comment-icon.png"
                      @click="btnComment(info.childrenCommentInfos[0])"
                    ></image>
                  </div>
                </div>
              </div>
            </view>
          </div>

          <div v-else>
            <view
              class="comment"
              v-for="children in info.childrenCommentInfos"
              :key="children.id"
            >
              <div class="c-left">
                <image :src="children.avatar"></image>
              </div>

              <div class="c-right">
                <div class="c-name">
                  {{ children.nickName }}
                  <div style="color: #333; margin-top: 10rpx">
                    回复
                    <text class="replyer">{{ children.beRepliedName }}:</text>
                    <text class="c-comment">{{ children.content }}</text>
                  </div>
                </div>
                <div class="c-actions">
                  <div class="c-time">{{ children.createTime }}</div>
                  <div class="action-item">
                    <image
                      @click="btnPrarse(children)"
                      :src="
                        children.praise
                          ? '/static/index/like-done.png'
                          : '/static/index/like-icon.png'
                      "
                    ></image>
                    {{ children.likesNumber }}
                  </div>
                  <div class="action-item">
                    <image
                      src="/static/index/comment-icon.png"
                      @click="btnComment(children)"
                    ></image>
                  </div>
                </div>
              </div>
            </view>
          </div>
          <div class="more">
            <div
              style="color: #b6ea7a"
              v-show="info.contentAll"
              @click="changeAllFun(info)"
            >
              展开剩余{{ info.childrenCommentInfos.length - 1 }}条回复
            </div>
            <div v-show="!info.contentAll"></div>
            <div
              v-show="!info.contentAll"
              style="color: #b6ea7a"
              @click="changeAllFun(info)"
            >
              收起
            </div>
          </div>
        </div>
      </div>
    </view>
  </div>
</template>

<script>
import { likeOrDislikeStrategy } from '@/service/index'
import Vue from 'vue'
// 引入bus文件
import bus from '../commen-item/bus'
// 发送消息  第一个参数为消息名(事件名),第二个参数为通信的值(可以不穿)
export default Vue.extend({
  props: {
    commentChildren: { type: Array, default: [] },
  },
  data () {
    return {
      title: 'Hello',
      totle: 0,
      flag: false,
    }
  },
  methods: {
    changeAllFun (info) {
      console.log(info)
      let list = this.commentChildren
      console.log(list)
      list.forEach((elem) => {
        console.log(elem.id == info.id)
        if (elem.id == info.id) {
          elem.contentAll = !elem.contentAll
        }
      })
      uni.setStorageSync("commentList", list)
      bus.$emit('resComList');
    },
    btnComment (item) {
      bus.$emit('item', item);
    },
    btnPrarse (info) {
      let list = uni.getStorageSync('commentList')
      let optType = null
      info.praise ? optType = 1 : optType = 0
      let parmars = {
        optType: optType,
        strategyCommentId: info.id,
      }

      likeOrDislikeStrategy(parmars).then(res => {
        if (res.code == 200) {
          this.seachId(list, info.id)
        }
        else {
          this.$toast(res.msg)
        }
      })
    },
    seachId (list, id) {
      let result = null
      for (let i = 0; i < list.length; i++) {
        if (result !== null) {
          break //跳出循环的关键
        }
        if (list[i].id === id) {
          let res = list[i].nickName;
          result = res //取值关键      
          list[i].praise = !list[i].praise
          if (list[i].praise) {
            list[i].likesNumber++
          } else {
            list[i].likesNumber--
          }
          break
        } else if (list[i].childrenCommentInfos) {//递归条件
          this.seachId(list[i].childrenCommentInfos, id);
        } else {
          continue
        }
      }
      uni.setStorageSync("commentList", list)
      bus.$emit('resComList');
    }
  },
})
</script>

<style lang="less">
.comment {
  display: flex;
  padding: 24rpx 0;
  border-top: 1rpx solid #ececec;

  .c-left {
    image {
      .wh(70rpx, 70rpx);
      border-radius: 50%;
    }
  }

  .c-right {
    flex: 1;
    margin-left: 22rpx;
    margin-top: 14rpx;
    .more {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
    .c-name {
      .replyer {
        color: #000;
        margin: 0 5px;
      }
      .sizeColor(32rpx, #000);
    }

    .c-comment {
      margin-top: 10rpx;
      .sizeColor(32rpx, #000);
      word-break: break-all;
    }

    .c-actions {
      margin-top: 20rpx;
      display: flex;
      justify-content: flex-end;

      .c-time {
        margin-right: auto;
        .sizeColor(20rpx, #999);
      }

      .action-item {
        display: flex;
        align-items: center;
        margin-right: 48rpx;
        .sizeColor(24rpx, #999);

        image {
          margin-right: 14rpx;
          .wh(28rpx, 24rpx);
        }
      }
    }
  }
}
</style>

有几个需要注意的
1、渲染多层的时候,并且需要调用父组件方法时,要使用vue的事件总线,否则找不到方法
2、不自己写一便是不知道问题的所在,代码有点臃肿,大佬勿喷,多谢指点

相关代码目录
在这里插入图片描述

gitee链接

https://gitee.com/wang_ya_ge/applet/tree/master,下载看看吧,src的代码也很有帮助

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐