comment-item.vue 4.33 KB
<template>
	<div class="comment-item">
		<ImageFormat :src="parentComment.headIco" :width="80" :height="80" class="comment-user-avatar"></ImageFormat>
		<div class="comment">
			<div class="comment-nav">
				<div class="comment-nav-left">
					<p class="comment-user-name">{{parentComment.userName || '&nbsp;'}}</p>
					<p class="comment-time">{{parentComment.createTime | time}}</p>
				</div>
				<WidgetFav
          class="comment-fav"
          :comment-id="parentComment.id"
          :num="parentComment.praiseTotal"
          :option="favOption"></WidgetFav>
			</div>

			<div class="comment-cont" @click="replyComment(parentComment.id)" :data-parent-id="parentComment.parentId" :data-root-id="parentComment.rootId">
				{{parentComment.content}}
			</div>
			<div class="reply-main" v-if="replayShowList.length">
				<p class="reply-item" v-for="(reply, replyIndex) in replayShowList" :key="replyIndex">
					<span class="reply-user">
						{{reply.userName}}
					</span>
					<span v-if="reply.parentUserName">
						回复<em class="reply-to-user">@{{reply.parentUserName}}</em>
					</span>:
					<span @click="replyComment(reply.id)" :data-parent-id="reply.parentId" :data-root-id="reply.rootId">
						{{reply.content}}
					</span>
				</p>
				<p class="reply-more" v-if="moreReplyNum > 0" @click="onShowMore">
          {{replyMoreText}}
          <i class="iconfont icon-right" v-if="!isShowAllReply"></i>
        </p>
			</div>
		</div>
	</div>
</template>

<script>
import {createNamespacedHelpers} from 'vuex';
const {mapActions} = createNamespacedHelpers('comment');

export default {
  name: 'CommentItem',
  props: {
    parentComment: Object,
    childrenComments: Array,
    columnType: {
      type: Number,
      default: 1001
    }
  },
  data() {
    return {
      isShowAllReply: false,
      limitNum: 2,
    };
  },
  computed: {
    favOption() {
      return {
        selected: this.parentComment.isPraise === 'Y'
      };
    },
    replayShowList() {
      if (this.childrenComments.length <= this.limitNum) {
        return this.childrenComments;
      }
      if (this.isShowAllReply) {
        return this.childrenComments;
      }
      return this.childrenComments.slice(0, this.limitNum);
    },
    moreReplyNum() {
      return this.childrenComments.length - this.limitNum;
    },
    replyMoreText() {
      return this.isShowAllReply ? '收起' : `查看${this.moreReplyNum}条回复`;
    }
  },
  methods: {
    ...mapActions(['postComment']),
    onShowMore() {
      this.isShowAllReply = !this.isShowAllReply;
    },
    async replyComment(commentId) {
      const result = await this.postComment({
        content: '这还是一条测试回复',
        commentId: commentId,
        addType: 1,
        columnType: this.columnType
      });

      if (result.code === 200) {
        this.$emit('on-reply', {commentId: this.parentComment.id});
      }
    }
  }
};
</script>

<style scoped lang="scss">
.comment-item {
  display: flex;
  margin-bottom: 40px;

  &:last-child {
    margin-bottom: 0;
  }

  .comment-user-avatar {
    width: 80px;
    height: 80px;
    border-radius: 50%;
  }

  .comment {
    width: 600px;
    margin-left: 10px;
  }

  .comment-nav {
    padding-left: 10px;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;
  }

  .comment-nav-left {
    flex: 1;

    .comment-user-name {
      font-size: 28px;
      font-weight: bold;
      color: #222;
      line-height: 40px;
      width: 100%;
      height: auto;
    }

    .comment-time {
      font-size: 20px;
      color: #b0b0b0;
      line-height: 28px;
      transform: scale(0.8);
      transform-origin: left;
    }
  }

  .comment-fav {
    padding-right: 20px;
  }

  .comment-cont {
    font-size: 28px;
    color: #444;
    line-height: 40px;
    margin: 12px 0 20px;
    padding-left: 10px;
    box-sizing: border-box;
  }

  .reply-main {
    background: #f0f0f0;
    padding: 20px;
    box-sizing: border-box;
    font-size: 24px;
    color: #444;
    line-height: 34px;
    margin-top: 20px;

    .reply-item {
      margin-bottom: 20px;
      display: flex;

      &:last-child {
        margin-bottom: 0;
      }

      .reply-to-user {
        color: #4a90e2;
        font-style: normal;
      }

      .reply-user {
        font-weight: 500;
      }
    }

    .reply-more {
      text-align: right;
      color: #4a90e2;
    }
  }
}
</style>