waterfall.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import { querySelector } from './query-node';
  2. const POSITION_LEFT = 'left';
  3. const POSITION_RIGHT = 'right';
  4. Component({
  5. externalClasses: ['custom-class'],
  6. properties: {
  7. loading: {
  8. type: Boolean,
  9. value: false,
  10. },
  11. isAllLoaded: {
  12. type: Boolean,
  13. value: false,
  14. },
  15. loadingText: {
  16. type: String,
  17. value: '正在加载中...'
  18. },
  19. allLoadedText: {
  20. type: String,
  21. value: '下面没有了哦 '
  22. },
  23. isUpdateFlow: {
  24. type: Number,
  25. value: 0,
  26. observer:function(newVal){
  27. this.setData({isUpdateFlow:newVal})
  28. this.childNumber = 0;
  29. wx.nextTick(() => {
  30. this.resetParam();
  31. const waterfallItems = this.getRelationNodes('./waterfall-item');
  32. waterfallItems.forEach((waterfallItem) => {
  33. this.childNumber += 1;
  34. waterfallItem.setWaterfallItemPosition();
  35. })
  36. })
  37. }
  38. },
  39. isEmpty: {
  40. type: Boolean,
  41. value: false,
  42. },
  43. emptyText: {
  44. type: String,
  45. value: '暂无数据'
  46. }
  47. },
  48. relations: {
  49. './waterfall-item': {
  50. type: 'child',
  51. linked(target) {
  52. if(this.childNumber) {
  53. this.childNumber += 1;
  54. } else {
  55. this.childNumber = 1;
  56. }
  57. }
  58. },
  59. },
  60. data: {
  61. waterfallHeight: 0,
  62. isShowAllLoadedTxt: false,
  63. },
  64. lifetimes: {
  65. ready() {
  66. this.initParams();
  67. this.setWatefallWidth();
  68. }
  69. },
  70. // observers: {
  71. // isUpdateFlow(value) {
  72. // if(value) {
  73. // this.childNumber = 0;
  74. // wx.nextTick(() => {
  75. // this.resetParam();
  76. // const waterfallItems = this.getRelationNodes('./waterfall-item');
  77. // waterfallItems.forEach((waterfallItem) => {
  78. // this.childNumber += 1;
  79. // waterfallItem.setWaterfallItemPosition();
  80. // })
  81. // })
  82. // }
  83. // }
  84. // },
  85. /**
  86. * 组件的方法列表
  87. */
  88. methods: {
  89. handleShowAllLoadedTxt(value) {
  90. if(this.data.isShowAllLoadedTxt === value) return;
  91. wx.nextTick(() => {
  92. setTimeout(() => {
  93. this.setData({
  94. isShowAllLoadedTxt: value
  95. })
  96. })
  97. })
  98. },
  99. initParams() {
  100. this.childCount = 0;
  101. this.itemGap = -1;
  102. this.waterfallWidth = -1;
  103. this.leftHeights = 0;
  104. this.rightHeights = 0;
  105. this.watefallItemIndex = 0;
  106. },
  107. resetParam() {
  108. this.childCount = 0;
  109. this.leftHeights = 0;
  110. this.rightHeights = 0;
  111. this.watefallItemIndex = 0;
  112. this.childNumber = 0;
  113. this.itemGap = -1;
  114. },
  115. /**
  116. * 设置 waterfall-item 的高度值
  117. * @param {Object} node waterfall-item 组件位置尺寸数据
  118. */
  119. async getWaterfallItemPostionInfo(node) {
  120. if(!node) return;
  121. let top = 0;
  122. const { height } = node;
  123. this.watefallItemIndex += 1;
  124. let position = POSITION_LEFT;
  125. const { itemGap } = this;
  126. if (this.leftHeights <= this.rightHeights) {
  127. top = this.leftHeights;
  128. if(this.leftHeights === 0) {
  129. this.leftHeights += height;
  130. } else {
  131. top += itemGap;
  132. this.leftHeights += height + itemGap;
  133. }
  134. } else {
  135. position = POSITION_RIGHT;
  136. top = this.rightHeights;
  137. if(this.rightHeights === 0) {
  138. this.rightHeights += height;
  139. } else {
  140. top += itemGap;
  141. this.rightHeights += height + itemGap;
  142. }
  143. }
  144. this.setWaterfallHeight(itemGap);
  145. return {
  146. top,
  147. position,
  148. }
  149. },
  150. async setWatefallWidth() {
  151. const info = await querySelector('.waterfall-inner', this);
  152. if(!info) {
  153. this.setWatefallWidth();
  154. return;
  155. }
  156. this.waterfallWidth = info.width;
  157. },
  158. async setWaterfallHeight(itemGap) {
  159. if(this.watefallItemIndex === this.childNumber) {
  160. let waterfallHeight = Math.ceil(Math.max(this.leftHeights, this.rightHeights) + itemGap);
  161. this.setData({
  162. waterfallHeight
  163. })
  164. const loadingNode = await querySelector('.placeholder', this);
  165. let nodeHeight = 0;
  166. if(loadingNode) {
  167. nodeHeight = loadingNode.height;
  168. }
  169. this.triggerEvent('finish', {
  170. waterfallHeight: nodeHeight + waterfallHeight
  171. })
  172. this.handleShowAllLoadedTxt(this.data.isAllLoaded)
  173. }
  174. }
  175. }
  176. })