index.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. exports.__esModule = true;
  4. exports.default = void 0;
  5. var _utils = require("../utils");
  6. var _style = require("../utils/dom/style");
  7. var _scroll = require("../utils/dom/scroll");
  8. var _bindEvent = require("../mixins/bind-event");
  9. var _loading = _interopRequireDefault(require("../loading"));
  10. // Utils
  11. // Mixins
  12. // Components
  13. var _createNamespace = (0, _utils.createNamespace)('list'),
  14. createComponent = _createNamespace[0],
  15. bem = _createNamespace[1],
  16. t = _createNamespace[2];
  17. var _default = createComponent({
  18. mixins: [(0, _bindEvent.BindEventMixin)(function (bind) {
  19. if (!this.scroller) {
  20. this.scroller = (0, _scroll.getScroller)(this.$el);
  21. }
  22. bind(this.scroller, 'scroll', this.check);
  23. })],
  24. model: {
  25. prop: 'loading'
  26. },
  27. props: {
  28. error: Boolean,
  29. loading: Boolean,
  30. finished: Boolean,
  31. errorText: String,
  32. loadingText: String,
  33. finishedText: String,
  34. immediateCheck: {
  35. type: Boolean,
  36. default: true
  37. },
  38. offset: {
  39. type: [Number, String],
  40. default: 300
  41. },
  42. direction: {
  43. type: String,
  44. default: 'down'
  45. }
  46. },
  47. data: function data() {
  48. return {
  49. // use sync innerLoading state to avoid repeated loading in some edge cases
  50. innerLoading: this.loading
  51. };
  52. },
  53. updated: function updated() {
  54. this.innerLoading = this.loading;
  55. },
  56. mounted: function mounted() {
  57. if (this.immediateCheck) {
  58. this.check();
  59. }
  60. },
  61. watch: {
  62. loading: 'check',
  63. finished: 'check'
  64. },
  65. methods: {
  66. // @exposed-api
  67. check: function check() {
  68. var _this = this;
  69. this.$nextTick(function () {
  70. if (_this.innerLoading || _this.finished || _this.error) {
  71. return;
  72. }
  73. var el = _this.$el,
  74. scroller = _this.scroller,
  75. offset = _this.offset,
  76. direction = _this.direction;
  77. var scrollerRect;
  78. if (scroller.getBoundingClientRect) {
  79. scrollerRect = scroller.getBoundingClientRect();
  80. } else {
  81. scrollerRect = {
  82. top: 0,
  83. bottom: scroller.innerHeight
  84. };
  85. }
  86. var scrollerHeight = scrollerRect.bottom - scrollerRect.top;
  87. /* istanbul ignore next */
  88. if (!scrollerHeight || (0, _style.isHidden)(el)) {
  89. return false;
  90. }
  91. var isReachEdge = false;
  92. var placeholderRect = _this.$refs.placeholder.getBoundingClientRect();
  93. if (direction === 'up') {
  94. isReachEdge = scrollerRect.top - placeholderRect.top <= offset;
  95. } else {
  96. isReachEdge = placeholderRect.bottom - scrollerRect.bottom <= offset;
  97. }
  98. if (isReachEdge) {
  99. _this.innerLoading = true;
  100. _this.$emit('input', true);
  101. _this.$emit('load');
  102. }
  103. });
  104. },
  105. clickErrorText: function clickErrorText() {
  106. this.$emit('update:error', false);
  107. this.check();
  108. },
  109. genLoading: function genLoading() {
  110. var h = this.$createElement;
  111. if (this.innerLoading && !this.finished) {
  112. return h("div", {
  113. "key": "loading",
  114. "class": bem('loading')
  115. }, [this.slots('loading') || h(_loading.default, {
  116. "attrs": {
  117. "size": "16"
  118. }
  119. }, [this.loadingText || t('loading')])]);
  120. }
  121. },
  122. genFinishedText: function genFinishedText() {
  123. var h = this.$createElement;
  124. if (this.finished) {
  125. var text = this.slots('finished') || this.finishedText;
  126. if (text) {
  127. return h("div", {
  128. "class": bem('finished-text')
  129. }, [text]);
  130. }
  131. }
  132. },
  133. genErrorText: function genErrorText() {
  134. var h = this.$createElement;
  135. if (this.error) {
  136. var text = this.slots('error') || this.errorText;
  137. if (text) {
  138. return h("div", {
  139. "on": {
  140. "click": this.clickErrorText
  141. },
  142. "class": bem('error-text')
  143. }, [text]);
  144. }
  145. }
  146. }
  147. },
  148. render: function render() {
  149. var h = arguments[0];
  150. var Placeholder = h("div", {
  151. "ref": "placeholder",
  152. "key": "placeholder",
  153. "class": bem('placeholder')
  154. });
  155. return h("div", {
  156. "class": bem(),
  157. "attrs": {
  158. "role": "feed",
  159. "aria-busy": this.innerLoading
  160. }
  161. }, [this.direction === 'down' ? this.slots() : Placeholder, this.genLoading(), this.genFinishedText(), this.genErrorText(), this.direction === 'up' ? this.slots() : Placeholder]);
  162. }
  163. });
  164. exports.default = _default;