comment-item.vue 3.9 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" :num="parentComment.praiseTotal"></WidgetFav>
			</div>

			<div class="comment-cont" @click="replyComment" :data-parent-id="parentComment.parentId" :data-root-id="parentComment.rootId">
				{{parentComment.content}}
			</div>
			<div class="reply-main" v-if="childrenComments.length">
				<p class="reply-item" v-for="(reply, replyIndex) in childrenComments" :key="replyIndex" v-show="isShowReply(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" :data-parent-id="reply.parentId" :data-root-id="reply.rootId">
						{{reply.content}}
					</span>
				</p>
				<p class="reply-more" v-if="isShowReplyMore" @click="viewMoreReply" v-html="replyMoreText"></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 {
      showAllReply: false,
      replyMoreText: '',
      moreText: ''
    };
  },
  computed: {
    isShowReplyMore() {
      return this.childrenComments.length > 2;
    },
    viewReplyNum() {
      return this.childrenComments.length - 2;
    }
  },
  created() {
    this.moreText = `查看${this.viewReplyNum}条回复<span class="iconfont icon-right"></span>`;
    this.replyMoreText = this.moreText;
  },
  methods: {
    ...mapActions(['postComment']),
    isShowReply(index) {
      return index <= 1 || this.showAllReply;
    },
    viewMoreReply() {
      this.replyMoreText = this.showAllReply ? this.moreText : '收起';
      this.showAllReply = !this.showAllReply;
    },
    replyComment() {
      this.postComment({
        content: '这还是一条测试回复',
        commentId: this.parentComment.id,
        addType: 1,
        columnType: this.columnType
      });
    }
  }
};
</script>

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

  &: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-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;

    .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;
      margin-top: 10px;
    }
  }
}
</style>