index.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 _event = require("../utils/dom/event");
  7. var _scroll = require("../utils/dom/scroll");
  8. var _touch = require("../mixins/touch");
  9. var _loading = _interopRequireDefault(require("../loading"));
  10. // Utils
  11. // Mixins
  12. // Components
  13. var _createNamespace = (0, _utils.createNamespace)('pull-refresh'),
  14. createComponent = _createNamespace[0],
  15. bem = _createNamespace[1],
  16. t = _createNamespace[2];
  17. var DEFAULT_HEAD_HEIGHT = 50;
  18. var TEXT_STATUS = ['pulling', 'loosing', 'success'];
  19. var _default = createComponent({
  20. mixins: [_touch.TouchMixin],
  21. props: {
  22. disabled: Boolean,
  23. successText: String,
  24. pullingText: String,
  25. loosingText: String,
  26. loadingText: String,
  27. pullDistance: [Number, String],
  28. value: {
  29. type: Boolean,
  30. required: true
  31. },
  32. successDuration: {
  33. type: [Number, String],
  34. default: 500
  35. },
  36. animationDuration: {
  37. type: [Number, String],
  38. default: 300
  39. },
  40. headHeight: {
  41. type: [Number, String],
  42. default: DEFAULT_HEAD_HEIGHT
  43. }
  44. },
  45. data: function data() {
  46. return {
  47. status: 'normal',
  48. distance: 0,
  49. duration: 0
  50. };
  51. },
  52. computed: {
  53. touchable: function touchable() {
  54. return this.status !== 'loading' && this.status !== 'success' && !this.disabled;
  55. },
  56. headStyle: function headStyle() {
  57. if (this.headHeight !== DEFAULT_HEAD_HEIGHT) {
  58. return {
  59. height: this.headHeight + "px"
  60. };
  61. }
  62. }
  63. },
  64. watch: {
  65. value: function value(loading) {
  66. this.duration = this.animationDuration;
  67. if (loading) {
  68. this.setStatus(+this.headHeight, true);
  69. } else if (this.slots('success') || this.successText) {
  70. this.showSuccessTip();
  71. } else {
  72. this.setStatus(0, false);
  73. }
  74. }
  75. },
  76. mounted: function mounted() {
  77. this.bindTouchEvent(this.$refs.track);
  78. this.scrollEl = (0, _scroll.getScroller)(this.$el);
  79. },
  80. methods: {
  81. checkPullStart: function checkPullStart(event) {
  82. this.ceiling = (0, _scroll.getScrollTop)(this.scrollEl) === 0;
  83. if (this.ceiling) {
  84. this.duration = 0;
  85. this.touchStart(event);
  86. }
  87. },
  88. onTouchStart: function onTouchStart(event) {
  89. if (this.touchable) {
  90. this.checkPullStart(event);
  91. }
  92. },
  93. onTouchMove: function onTouchMove(event) {
  94. if (!this.touchable) {
  95. return;
  96. }
  97. if (!this.ceiling) {
  98. this.checkPullStart(event);
  99. }
  100. this.touchMove(event);
  101. if (this.ceiling && this.deltaY >= 0 && this.direction === 'vertical') {
  102. (0, _event.preventDefault)(event);
  103. this.setStatus(this.ease(this.deltaY));
  104. }
  105. },
  106. onTouchEnd: function onTouchEnd() {
  107. var _this = this;
  108. if (this.touchable && this.ceiling && this.deltaY) {
  109. this.duration = this.animationDuration;
  110. if (this.status === 'loosing') {
  111. this.setStatus(+this.headHeight, true);
  112. this.$emit('input', true); // ensure value change can be watched
  113. this.$nextTick(function () {
  114. _this.$emit('refresh');
  115. });
  116. } else {
  117. this.setStatus(0);
  118. }
  119. }
  120. },
  121. ease: function ease(distance) {
  122. var pullDistance = +(this.pullDistance || this.headHeight);
  123. if (distance > pullDistance) {
  124. if (distance < pullDistance * 2) {
  125. distance = pullDistance + (distance - pullDistance) / 2;
  126. } else {
  127. distance = pullDistance * 1.5 + (distance - pullDistance * 2) / 4;
  128. }
  129. }
  130. return Math.round(distance);
  131. },
  132. setStatus: function setStatus(distance, isLoading) {
  133. var status;
  134. if (isLoading) {
  135. status = 'loading';
  136. } else if (distance === 0) {
  137. status = 'normal';
  138. } else {
  139. status = distance < (this.pullDistance || this.headHeight) ? 'pulling' : 'loosing';
  140. }
  141. this.distance = distance;
  142. if (status !== this.status) {
  143. this.status = status;
  144. }
  145. },
  146. genStatus: function genStatus() {
  147. var h = this.$createElement;
  148. var status = this.status,
  149. distance = this.distance;
  150. var slot = this.slots(status, {
  151. distance: distance
  152. });
  153. if (slot) {
  154. return slot;
  155. }
  156. var nodes = [];
  157. var text = this[status + "Text"] || t(status);
  158. if (TEXT_STATUS.indexOf(status) !== -1) {
  159. nodes.push(h("div", {
  160. "class": bem('text')
  161. }, [text]));
  162. }
  163. if (status === 'loading') {
  164. nodes.push(h(_loading.default, {
  165. "attrs": {
  166. "size": "16"
  167. }
  168. }, [text]));
  169. }
  170. return nodes;
  171. },
  172. showSuccessTip: function showSuccessTip() {
  173. var _this2 = this;
  174. this.status = 'success';
  175. setTimeout(function () {
  176. _this2.setStatus(0);
  177. }, this.successDuration);
  178. }
  179. },
  180. render: function render() {
  181. var h = arguments[0];
  182. var trackStyle = {
  183. transitionDuration: this.duration + "ms",
  184. transform: this.distance ? "translate3d(0," + this.distance + "px, 0)" : ''
  185. };
  186. return h("div", {
  187. "class": bem()
  188. }, [h("div", {
  189. "ref": "track",
  190. "class": bem('track'),
  191. "style": trackStyle
  192. }, [h("div", {
  193. "class": bem('head'),
  194. "style": this.headStyle
  195. }, [this.genStatus()]), this.slots()])]);
  196. }
  197. });
  198. exports.default = _default;