index.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import { use } from '../utils';
  2. import { preventDefault } from '../utils/event';
  3. import { TouchMixin } from '../mixins/touch';
  4. import { getScrollTop, getScrollEventTarget } from '../utils/scroll';
  5. import Loading from '../loading';
  6. var _use = use('pull-refresh'),
  7. sfc = _use[0],
  8. bem = _use[1],
  9. t = _use[2];
  10. var TEXT_STATUS = ['pulling', 'loosing', 'success'];
  11. export default sfc({
  12. mixins: [TouchMixin],
  13. props: {
  14. disabled: Boolean,
  15. successText: String,
  16. pullingText: String,
  17. loosingText: String,
  18. loadingText: String,
  19. value: {
  20. type: Boolean,
  21. required: true
  22. },
  23. successDuration: {
  24. type: Number,
  25. "default": 500
  26. },
  27. animationDuration: {
  28. type: Number,
  29. "default": 300
  30. },
  31. headHeight: {
  32. type: Number,
  33. "default": 50
  34. }
  35. },
  36. data: function data() {
  37. return {
  38. status: 'normal',
  39. height: 0,
  40. duration: 0
  41. };
  42. },
  43. computed: {
  44. untouchable: function untouchable() {
  45. return this.status === 'loading' || this.status === 'success' || this.disabled;
  46. }
  47. },
  48. watch: {
  49. value: function value(loading) {
  50. var _this = this;
  51. this.duration = this.animationDuration;
  52. if (!loading && this.successText) {
  53. this.status = 'success';
  54. setTimeout(function () {
  55. _this.setStatus(0);
  56. }, this.successDuration);
  57. } else {
  58. this.setStatus(loading ? this.headHeight : 0, loading);
  59. }
  60. }
  61. },
  62. mounted: function mounted() {
  63. this.scrollEl = getScrollEventTarget(this.$el);
  64. },
  65. methods: {
  66. onTouchStart: function onTouchStart(event) {
  67. if (!this.untouchable && this.getCeiling()) {
  68. this.duration = 0;
  69. this.touchStart(event);
  70. }
  71. },
  72. onTouchMove: function onTouchMove(event) {
  73. if (this.untouchable) {
  74. return;
  75. }
  76. this.touchMove(event);
  77. if (!this.ceiling && this.getCeiling()) {
  78. this.duration = 0;
  79. this.startY = event.touches[0].clientY;
  80. this.deltaY = 0;
  81. }
  82. if (this.ceiling && this.deltaY >= 0) {
  83. if (this.direction === 'vertical') {
  84. this.setStatus(this.ease(this.deltaY));
  85. preventDefault(event);
  86. }
  87. }
  88. },
  89. onTouchEnd: function onTouchEnd() {
  90. if (!this.untouchable && this.ceiling && this.deltaY) {
  91. this.duration = this.animationDuration;
  92. if (this.status === 'loosing') {
  93. this.setStatus(this.headHeight, true);
  94. this.$emit('input', true);
  95. this.$emit('refresh');
  96. } else {
  97. this.setStatus(0);
  98. }
  99. }
  100. },
  101. getCeiling: function getCeiling() {
  102. this.ceiling = getScrollTop(this.scrollEl) === 0;
  103. return this.ceiling;
  104. },
  105. ease: function ease(height) {
  106. var headHeight = this.headHeight;
  107. return height < headHeight ? height : height < headHeight * 2 ? Math.round(headHeight + (height - headHeight) / 2) : Math.round(headHeight * 1.5 + (height - headHeight * 2) / 4);
  108. },
  109. setStatus: function setStatus(height, isLoading) {
  110. this.height = height;
  111. var status = isLoading ? 'loading' : height === 0 ? 'normal' : height < this.headHeight ? 'pulling' : 'loosing';
  112. if (status !== this.status) {
  113. this.status = status;
  114. }
  115. }
  116. },
  117. render: function render(h) {
  118. var status = this.status;
  119. var text = this[status + "Text"] || t(status);
  120. var style = {
  121. transition: this.duration + "ms",
  122. transform: this.height ? "translate3d(0," + this.height + "px, 0)" : ''
  123. };
  124. var Status = this.slots(status) || [TEXT_STATUS.indexOf(status) !== -1 && h("div", {
  125. "class": bem('text')
  126. }, [text]), status === 'loading' && h("div", {
  127. "class": bem('loading')
  128. }, [h(Loading), h("span", [text])])];
  129. return h("div", {
  130. "class": bem()
  131. }, [h("div", {
  132. "class": bem('track'),
  133. "style": style,
  134. "on": {
  135. "touchstart": this.onTouchStart,
  136. "touchmove": this.onTouchMove,
  137. "touchend": this.onTouchEnd,
  138. "touchcancel": this.onTouchEnd
  139. }
  140. }, [h("div", {
  141. "class": bem('head')
  142. }, [Status]), this.slots()])]);
  143. }
  144. });