w-waterfall.vue 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <template>
  2. <view class="waterfall-list-container">
  3. <view class="waterfall-list" v-for="(item, index) in columnCount" :key="index"
  4. :style="{
  5. width: width,
  6. marginLeft: index === 0 ? '0' : `${itemGap}rpx`,
  7. marginRight: index === columnCount - 1 ? '0' : `${itemGap}rpx`
  8. }">
  9. <view v-for="(el, i) in list[index]" :key="i">
  10. <slot name="content" :item="el" :width="width" />
  11. </view>
  12. </view>
  13. </view>
  14. </template>
  15. <script>
  16. export default {
  17. name: "w-waterfall",
  18. props: {
  19. sideGap: {
  20. type: Number,
  21. default: 5
  22. },
  23. itemGap: {
  24. type: Number,
  25. default: 10
  26. },
  27. columnCount: {
  28. type: Number,
  29. default: 2,
  30. },
  31. data: {
  32. type: Array,
  33. default: () => ([])
  34. }
  35. },
  36. watch: {
  37. data: {
  38. handler(newV) {
  39. if (newV.length != 0) {
  40. this.init()
  41. }
  42. },
  43. immediate: true
  44. }
  45. },
  46. mounted() {
  47. const screenWidth = uni.getWindowInfo().screenWidth;
  48. const screenRate = screenWidth / 750;
  49. const gap = ((this.columnCount - 1) * this.itemGap) + this.sideGap;
  50. const itemWidth = (screenWidth - gap) / this.columnCount
  51. this.width = Math.round(itemWidth * (1 / screenRate)) - 40/this.columnCount + 'rpx'
  52. },
  53. data() {
  54. return {
  55. width: '',
  56. list: []
  57. };
  58. },
  59. methods: {
  60. init() {
  61. let list = []
  62. for (let i = 0; i < this.columnCount; i++) {
  63. list[i] = []
  64. }
  65. let i = 0
  66. this.data.forEach((el, index) => {
  67. if (i > this.columnCount - 1) {
  68. i = 0
  69. }
  70. list[i].push(el)
  71. i++
  72. })
  73. this.list = list
  74. },
  75. }
  76. }
  77. </script>
  78. <style lang="scss">
  79. .waterfall-list-container {
  80. // #ifdef APP-NVUE
  81. // #endif
  82. // #ifndef APP-NVUE
  83. // #endif
  84. display: flex;
  85. flex-direction: row;
  86. justify-content: space-between;
  87. padding: 0 20rpx;
  88. }
  89. </style>