index.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { getHeight } from "../../utils/getHeight";
  2. Component({
  3. properties: {
  4. height: {
  5. type: Number
  6. },
  7. pullDown: {
  8. type: Boolean,
  9. value: true
  10. },
  11. safety: {
  12. type: Boolean,
  13. value: true
  14. },
  15. automatic: {
  16. type: Boolean,
  17. value: true
  18. },
  19. loading: {
  20. type: Boolean,
  21. value: false,
  22. observer: "onLoadingChange"
  23. },
  24. finished: {
  25. type: Boolean,
  26. value: false
  27. },
  28. empty: {
  29. type: Boolean,
  30. value: false
  31. },
  32. scrollTop: {
  33. type: Number,
  34. value: 0,
  35. observer: "scrollToTop"
  36. },
  37. showScrollbar: {
  38. type: Boolean,
  39. value: false
  40. },
  41. lowerThreshold: {
  42. type: Number,
  43. value: 300
  44. },
  45. finishedText: {
  46. type: String,
  47. value: "没有更多了"
  48. },
  49. emptyText: {
  50. type: String,
  51. value: "暂无数据"
  52. },
  53. loadingText: {
  54. type: String,
  55. value: "加载中..."
  56. }
  57. },
  58. lifetimes: {
  59. attached() {
  60. if (this.data.automatic) this.automaticSetHei();
  61. },
  62. detached() {
  63. this._detached = true;
  64. if (this._refreshTimer) {
  65. clearTimeout(this._refreshTimer);
  66. this._refreshTimer = null;
  67. }
  68. }
  69. },
  70. data: {
  71. inRefresh: false,
  72. _innerScrollTop: 0
  73. },
  74. methods: {
  75. /* 回到顶部 */
  76. goTop() {
  77. const ts = Date.now();
  78. this.setData({ _innerScrollTop: ts }, () => {
  79. if (!this._detached) {
  80. this.setData({ _innerScrollTop: 0 });
  81. }
  82. });
  83. },
  84. /* 下拉刷新 */
  85. pullToRefresh() {
  86. if (this.data.inRefresh) return;
  87. this.setData({ inRefresh: true });
  88. this.triggerEvent("getlist", true);
  89. },
  90. /* 刷新完成 - 父组件在接口返回后调用 */
  91. RefreshToComplete() {
  92. if (this._refreshTimer) clearTimeout(this._refreshTimer);
  93. this._refreshTimer = setTimeout(() => {
  94. if (this._detached) return;
  95. this.setData({ inRefresh: false });
  96. this._refreshTimer = null;
  97. }, 500);
  98. },
  99. /* 触底加载 - 内部立即加锁,防止接口返回前重复触发 */
  100. loadThePage() {
  101. if (this._loadingLocked || this.data.inRefresh || this.data.loading || this.data.finished) return;
  102. this._loadingLocked = true;
  103. this.triggerEvent("getlist", false);
  104. },
  105. /* 分页加载完成 - 父组件在接口返回后调用,解锁以允许下次触底 */
  106. completeLoad() {
  107. this._loadingLocked = false;
  108. if (!this._detached) {
  109. this.setData({ loading: false });
  110. }
  111. },
  112. /* 重置分页状态(如切换筛选项时调用) */
  113. resetLoad() {
  114. this._loadingLocked = false;
  115. if (!this._detached) {
  116. this.setData({ loading: false, finished: false, empty: false });
  117. }
  118. },
  119. /* loading 属性变化时同步内部锁 */
  120. onLoadingChange(val) {
  121. if (!val) {
  122. this._loadingLocked = false;
  123. }
  124. },
  125. scrollToTop(val) {
  126. if (val !== this.data._innerScrollTop) {
  127. this.setData({ _innerScrollTop: val });
  128. }
  129. },
  130. automaticSetHei(mode, num) {
  131. this.setHeight("#mylisttop", mode, num);
  132. },
  133. setHeight(element, mode, num) {
  134. return getHeight(element, this).then(res => {
  135. let height = res;
  136. if (mode === "add") {
  137. height = res + num;
  138. } else if (mode === "minus") {
  139. height = res - num;
  140. }
  141. if (!this._detached) {
  142. this.setData({ height });
  143. }
  144. return height;
  145. });
  146. }
  147. }
  148. });