scs-helang-waterfall.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <template>
  2. <!--
  3. * @Author: jmy
  4. * @Date: 2026-01-09 12:02:41
  5. * @LastEditors: Please set LastEditors
  6. * @LastEditTime: 2026-01-09 15:02:20
  7. * @Description: helang瀑布流组件
  8. -->
  9. <view class="px-12 mt-14 flex justify-between gap-11">
  10. <view class="flex-1" :style="{ gap: gapValue + 'px' }" v-for="(column, columnIndex) in columnCount"
  11. :key="columnIndex">
  12. <view v-for="(item, index) in getColumnwaterfallList(columnIndex)" :key="item.id || index"
  13. class="w-all relative rounded-8 overflow-hidden prodoct-item mb-11">
  14. <slot name="special"></slot>
  15. <view class="w-all h-171 relative rounded-t-8 overflow-hidden">
  16. <image class="w-all h-171 bg-img" :src="item.image" lazy-load @load="handleImageLoad(item.id)"
  17. :class="{ 'opacity-10': isImageLoaded(item.id), 'opacity-0': !isImageLoaded(item.id) }"
  18. mode="aspectFill"></image>
  19. <!-- 加载中显示占位符 -->
  20. <view v-if="!isImageLoaded(item.id)"
  21. class="w-all h-171 absolute top-0 left-0 flex items-center justify-center bg-gray-100">
  22. <text class="scroll-loading scroll-rotate"></text>
  23. </view>
  24. </view>
  25. <slot name="default" :item="item"></slot>
  26. </view>
  27. </view>
  28. </view>
  29. </template>
  30. <script>
  31. export default {
  32. props: {
  33. waterfallList: {
  34. type: Array,
  35. default: () => [
  36. {
  37. id: 1,
  38. image: 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422',
  39. title: '云南白药EGER每瓶重50g保险液每测试',
  40. },
  41. {
  42. id: 2,
  43. image: 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422',
  44. title: '云南白药EGER每瓶重50g保险液每测试',
  45. },
  46. ]
  47. },
  48. calcGap: {
  49. type: Number,
  50. default: 11
  51. },
  52. columnCount: {
  53. type: Number,
  54. default: 2
  55. }
  56. },
  57. data() {
  58. return {
  59. // 默认示例数据
  60. defaultwaterfallList: [
  61. ],
  62. // 图片加载状态管理
  63. imageLoadingStatus: {}
  64. }
  65. },
  66. computed: {
  67. gapValue() {
  68. return this.calcGap / this.columnCount
  69. }
  70. },
  71. methods: {
  72. // 检查图片是否已加载
  73. isImageLoaded(id) {
  74. // 特殊项(本地图片)默认已加载
  75. if (!id) return true;
  76. return this.imageLoadingStatus[id] === true;
  77. },
  78. // 处理图片加载完成事件
  79. handleImageLoad(id) {
  80. if (id) {
  81. this.$set(this.imageLoadingStatus, id, true);
  82. }
  83. },
  84. // 按列分配数据项
  85. getColumnwaterfallList(columnIndex) {
  86. const waterfallList = [];
  87. const columnCount = 2;
  88. // 将数据项分配到不同列
  89. this.waterfallList.forEach((item, index) => {
  90. if (index % columnCount === columnIndex) {
  91. waterfallList.push(item);
  92. }
  93. });
  94. return waterfallList;
  95. }
  96. }
  97. }
  98. </script>
  99. <style lang="scss" scoped></style>