CommentPopup.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <Popup title="查看评论" isClose ref="popRef">
  3. <!-- 评论内容 -->
  4. <template #content>
  5. <view class="comment-container">
  6. <view class="comment-content">
  7. {{ commentDetail.content || $t("暂无评论内容") }}
  8. </view>
  9. <ImageGrid
  10. :images="commentDetail.images"
  11. v-if="commentDetail.images && commentDetail.images.length"
  12. />
  13. </view>
  14. </template>
  15. <!-- 底部按钮 -->
  16. <template #footer>
  17. <view class="btn-group">
  18. <view class="cancel-btn" @click="close">
  19. <trans _t="关闭" />
  20. </view>
  21. </view>
  22. </template>
  23. </Popup>
  24. </template>
  25. <script setup>
  26. import { computed, ref, onMounted, watch } from "vue";
  27. import Popup from "@/components/popup.vue";
  28. import ImageGrid from "@/components/ImageGrid.vue";
  29. import { t } from "@/locale";
  30. import { SHOP_SHOW_COMMENTS } from "@/api";
  31. import { urlStrToArr } from "@/utils";
  32. // 组件props:接收评论ID
  33. const props = defineProps({
  34. commentId: {
  35. type: [String, Number],
  36. required: true,
  37. default: "",
  38. },
  39. });
  40. const emit = defineEmits(["open", "close", "fetchSuccess", "fetchFail"]);
  41. const popRef = ref(null);
  42. // 评论数据
  43. const commentDetail = ref({});
  44. const fetchCommentDetail = async (id) => {
  45. try {
  46. const res = await SHOP_SHOW_COMMENTS(id);
  47. commentDetail.value = res.data;
  48. commentDetail.value.images = urlStrToArr(commentDetail.value.images);
  49. popRef.value && popRef.value.open();
  50. emit("fetchSuccess", res.data);
  51. } catch (err) {
  52. emit("fetchFail", { msg: errorMsg.value, error: err });
  53. }
  54. };
  55. // 监听commentId变化,重新请求数据
  56. watch(
  57. () => props.commentId,
  58. (newId) => {
  59. if (newId && popRef.value?.isShow) {
  60. fetchCommentDetail(newId);
  61. }
  62. },
  63. { immediate: false }
  64. );
  65. // 打开弹框
  66. const open = (id) => {
  67. fetchCommentDetail(id);
  68. emit("open");
  69. };
  70. // 关闭弹框
  71. const close = () => {
  72. emit("close");
  73. if (popRef.value) {
  74. popRef.value.close();
  75. // 关闭后重置数据
  76. commentDetail.value = {};
  77. }
  78. };
  79. // 暴露方法给父组件
  80. defineExpose({ open, close, fetchCommentDetail });
  81. </script>
  82. <style lang="less" scoped>
  83. @import url("@/style.less");
  84. .comment-container {
  85. width: 100%;
  86. /* 评论内容样式 */
  87. .comment-content {
  88. color: var(--text-01);
  89. .size(24rpx);
  90. line-height: 40rpx;
  91. margin-bottom: 30rpx;
  92. white-space: pre-wrap;
  93. }
  94. }
  95. .btn-group {
  96. display: flex;
  97. gap: 20rpx;
  98. width: 100%;
  99. .cancel-btn,
  100. .preview-original-btn {
  101. flex: 1;
  102. height: 38px;
  103. display: flex;
  104. align-items: center;
  105. justify-content: center;
  106. border-radius: 16rpx;
  107. .size(24rpx);
  108. }
  109. .cancel-btn {
  110. background-color: var(--black);
  111. color: var(--light);
  112. }
  113. .preview-original-btn {
  114. background-color: #f5f5f5;
  115. color: var(--text-01);
  116. border: 2rpx solid #e5e5e5;
  117. }
  118. }
  119. /* 旋转动画 */
  120. @keyframes spin {
  121. from {
  122. transform: rotate(0deg);
  123. }
  124. to {
  125. transform: rotate(360deg);
  126. }
  127. }
  128. </style>