w-waterfall.vue 1.6 KB

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