index.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <template>
  2. <view :class="classes" v-if="info && Object.keys(info)">
  3. <!-- 根据展示信息的多少,分为3种展示风格:simple,base,complex -->
  4. <comment-header :type="headerType" :info="info" :labels="labels" @handleClick="handleClick">
  5. <template #labels>
  6. <slot name="comment-labels"></slot>
  7. </template>
  8. </comment-header>
  9. <slot name="feature"></slot>
  10. <view
  11. class="nut-comment__main"
  12. :style="`-webkit-line-clamp:${conEllipsis}`"
  13. @click="handleClick"
  14. v-html="info.content.replace(/\n/g, '<br>')"
  15. ></view>
  16. <comment-images :images="images" :videos="videos" :type="imagesRows" @clickImages="clickImages"></comment-images>
  17. <view class="nut-comment__follow" v-if="follow && follow.days > 0" @click="handleClick">
  18. <view class="nut-comment__follow-title"
  19. ><nut-icon size="14" name="joy-smile" />{{ translate('additionalReview', follow.days) }}</view
  20. >
  21. <view class="nut-comment__follow-com">{{ follow.content }}</view>
  22. <view class="nut-comment__follow-img" v-if="follow.images && follow.images.length > 0"
  23. >{{ translate('additionalImages', follow.images.length) }} <nut-icon size="12" name="right"
  24. /></view>
  25. </view>
  26. <comment-bottom
  27. :type="headerType"
  28. :info="info"
  29. :operation="operation"
  30. @clickOperate="clickOperate"
  31. @handleClick="handleClick"
  32. ></comment-bottom>
  33. <slot name="comment-shop-reply"></slot>
  34. </view>
  35. </template>
  36. <script lang="ts">
  37. import { ref, onMounted, computed, watch } from 'vue';
  38. import { createComponent } from '../../utils/create';
  39. const { componentName, create, translate } = createComponent('comment');
  40. import CommentHeader from './components/CmtHeader.vue';
  41. import CommentImages from './components/CmtImages.vue';
  42. import CommentBottom from './components/CmtBottom.vue';
  43. export default create({
  44. props: {
  45. headerType: {
  46. type: String,
  47. default: 'default' //头部展示风格 default,complex
  48. },
  49. imagesRows: {
  50. type: String,
  51. default: 'one' // 'one' 'multi'
  52. },
  53. ellipsis: {
  54. type: [String, Number, Boolean],
  55. default: false
  56. },
  57. videos: {
  58. type: Array,
  59. default: () => []
  60. },
  61. images: {
  62. type: Array,
  63. default: () => []
  64. },
  65. info: {
  66. type: Object,
  67. default: () => {}
  68. },
  69. follow: {
  70. type: Object,
  71. default: () => {}
  72. },
  73. labels: {
  74. type: Function,
  75. default: () => ''
  76. },
  77. operation: {
  78. type: Array,
  79. default: ['replay', 'like', 'more']
  80. }
  81. },
  82. components: {
  83. CommentHeader,
  84. CommentImages,
  85. CommentBottom
  86. },
  87. emits: ['click', 'clickImages', 'clickOperate'],
  88. setup(props, { emit }) {
  89. const classes = computed(() => {
  90. const prefixCls = componentName;
  91. return {
  92. [prefixCls]: true
  93. };
  94. });
  95. const conEllipsis = computed(() => {
  96. if (props.ellipsis) return props.ellipsis;
  97. return props.headerType == 'complex' ? 6 : 2;
  98. });
  99. const clickOperate = (t: string) => {
  100. emit('clickOperate', t);
  101. };
  102. const handleClick = () => {
  103. emit('click', props.info);
  104. };
  105. const clickImages = (value: any) => {
  106. emit('clickImages', value);
  107. };
  108. return { classes, conEllipsis, clickOperate, handleClick, clickImages, translate };
  109. }
  110. });
  111. </script>