post-image-grid.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <template>
  2. <view class="pig" :class="'pig--' + columns">
  3. <!-- 单图 -->
  4. <view
  5. v-if="columns === 1"
  6. class="pig-single"
  7. @tap.stop="onTap(0)"
  8. >
  9. <image class="pig-single-img" :src="cellSrc(visible[0], 750)" mode="aspectFill" />
  10. </view>
  11. <!-- 多图网格 -->
  12. <view v-else class="pig-grid">
  13. <view
  14. v-for="(img, idx) in visible"
  15. :key="idx"
  16. class="pig-cell"
  17. :class="'pig-cell--' + columns"
  18. @tap.stop="onTap(idx)"
  19. >
  20. <image class="pig-cell-img" :src="cellSrc(img, 360)" mode="aspectFill" />
  21. <view v-if="idx === visible.length - 1 && overflow > 0" class="pig-overflow">
  22. <text class="pig-overflow-text">+{{ overflow }}</text>
  23. </view>
  24. </view>
  25. </view>
  26. </view>
  27. </template>
  28. <script>
  29. import { gridColumnCount, gridDisplayImages } from '@/features/dynamics/post-media'
  30. export default {
  31. name: 'PostImageGrid',
  32. props: {
  33. images: { type: Array, default: () => [] },
  34. max: { type: Number, default: 9 }
  35. },
  36. computed: {
  37. pack() {
  38. return gridDisplayImages(this.images, this.max)
  39. },
  40. visible() {
  41. return this.pack.visible
  42. },
  43. overflow() {
  44. return this.pack.overflow
  45. },
  46. count() {
  47. return this.visible.length
  48. },
  49. columns() {
  50. return gridColumnCount(this.count)
  51. }
  52. },
  53. methods: {
  54. oss(url, w = 400, h = 0) {
  55. if (this.$appKit && typeof this.$appKit.oss === 'function') {
  56. return this.$appKit.oss(url, w, h)
  57. }
  58. return url || ''
  59. },
  60. cellSrc(url, w) {
  61. return this.oss(url, w, w)
  62. },
  63. onTap(index) {
  64. this.$emit('tap-image', index)
  65. }
  66. }
  67. }
  68. </script>
  69. <style scoped>
  70. .pig {
  71. width: 100%;
  72. }
  73. .pig-single {
  74. width: 100%;
  75. height: 420rpx;
  76. border-radius: 20rpx;
  77. overflow: hidden;
  78. background-color: #eef2f8;
  79. }
  80. .pig-single-img {
  81. width: 100%;
  82. height: 100%;
  83. }
  84. .pig-grid {
  85. display: flex;
  86. flex-direction: row;
  87. flex-wrap: wrap;
  88. width: 100%;
  89. justify-content: flex-start;
  90. }
  91. .pig-cell {
  92. position: relative;
  93. border-radius: 12rpx;
  94. overflow: hidden;
  95. background-color: #eef2f8;
  96. margin-bottom: 8rpx;
  97. }
  98. .pig-cell--2 {
  99. width: 49%;
  100. height: 280rpx;
  101. }
  102. .pig-cell--2:nth-child(2n) {
  103. margin-left: 2%;
  104. }
  105. .pig-cell--3 {
  106. width: 32%;
  107. height: 210rpx;
  108. margin-right: 2%;
  109. }
  110. .pig-cell--3:nth-child(3n) {
  111. margin-right: 0;
  112. }
  113. .pig-cell-img {
  114. width: 100%;
  115. height: 100%;
  116. }
  117. .pig-overflow {
  118. position: absolute;
  119. left: 0;
  120. right: 0;
  121. top: 0;
  122. bottom: 0;
  123. background-color: rgba(0, 0, 0, 0.45);
  124. display: flex;
  125. align-items: center;
  126. justify-content: center;
  127. }
  128. .pig-overflow-text {
  129. color: #ffffff;
  130. font-size: 40rpx;
  131. font-weight: 700;
  132. }
  133. </style>