y-Refresh.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <template>
  2. <!-- #ifdef H5 -->
  3. <view
  4. class="mix-refresh-content"
  5. :style="{
  6. transform: 'translateY('+ pageDeviation +'px)',
  7. transition: pageTransition + 's',
  8. height: 'calc(100% - ' + pageTop + 'px)',
  9. maxHeight: 'calc(100% - ' + pageTop + 'px)'
  10. }"
  11. @touchstart="pageTouchstart"
  12. @touchmove="pageTouchmove"
  13. @touchend="pageTouchend"
  14. >
  15. <!-- #endif -->
  16. <!-- #ifndef H5 -->
  17. <view
  18. class="mix-refresh-content"
  19. :style="{
  20. transform: 'translateY('+ pageDeviation +'px)',
  21. transition: pageTransition + 's',
  22. height: 'calc(100vh - ' + pageTop + 'px)',
  23. maxHeight: 'calc(100vh - ' + pageTop + 'px)'
  24. }"
  25. @touchstart="pageTouchstart"
  26. @touchmove="pageTouchmove"
  27. @touchend="pageTouchend"
  28. >
  29. <!-- #endif -->
  30. <!-- 下拉刷新 -->
  31. <view class="mix-loading-wrapper">
  32. <text class="cuIcon-icloading cu-load loading"></text>
  33. <text>既许一人之偏爱,愿尽余生之慷慨</text>
  34. </view>
  35. <slot></slot>
  36. </view>
  37. </template>
  38. <script>
  39. let startY, moveY, windowHeight = 500, platform;
  40. let timeDiff = 0;
  41. let touchending;
  42. export default {
  43. props: {
  44. top: {
  45. //距离顶部距离,单位upx
  46. type: Number,
  47. default: 0
  48. },
  49. },
  50. data() {
  51. return {
  52. pageDeviation: 0, //下偏移量
  53. pageTransition: 0, //回弹过渡时间
  54. refreshReady: false, //进入刷新准备状态
  55. refreshing: false, // 进入刷新状态
  56. loadingText: ['人前显贵,人后受罪']
  57. };
  58. },
  59. computed: {
  60. pageTop(){
  61. return uni.upx2px(this.top);
  62. }
  63. },
  64. created(){
  65. uni.getSystemInfo({
  66. success: function(e) {
  67. platform = e.platform;
  68. windowHeight = e.windowHeight;
  69. }
  70. })
  71. },
  72. methods: {
  73. pageTouchstart(e){
  74. touchending = false;
  75. this.pageTransition = 0;
  76. startY = e.touches[0].pageY;
  77. },
  78. pageTouchmove(e){
  79. if(touchending){
  80. return;
  81. }
  82. moveY = (e.touches[0].pageY - startY) * 0.4;
  83. if(moveY >= 0){
  84. this.pageDeviation = moveY;
  85. this.$emit('setEnableScroll', false);
  86. }
  87. if(moveY >= 50 && this.refreshReady === false){
  88. this.refreshReady = true;
  89. }else if(moveY < 50 && this.refreshReady === true){
  90. this.refreshReady = false;
  91. }
  92. if(platform === 'ios' && e.touches[0].pageY > windowHeight + 10){
  93. this.pageTouchend();
  94. }
  95. },
  96. pageTouchend(){
  97. touchending = true;
  98. if(moveY === 0){
  99. return;
  100. }
  101. this.pageTransition = 0.3;
  102. if(moveY >= 50){
  103. this.startPulldownRefresh();
  104. }else{
  105. this.pageDeviation = 0;
  106. }
  107. if(this.refreshReady === true){
  108. this.refreshReady = false;
  109. }
  110. //修复下拉一点回弹后页面无法滚动的bug
  111. this.$emit('setEnableScroll', true);
  112. startY = moveY = 0;
  113. },
  114. //开启下拉刷新
  115. startPulldownRefresh(){
  116. if(+new Date() - timeDiff < 100){
  117. return;
  118. }
  119. timeDiff = +new Date();
  120. this.refreshing = true;
  121. this.pageDeviation = uni.upx2px(90);
  122. this.$emit('refresh');
  123. },
  124. //结束下拉刷新
  125. endPulldownRefresh(){
  126. let that = this
  127. setTimeout(function(){
  128. that.refreshing = false;
  129. that.pageDeviation = uni.upx2px(0);
  130. },1200)
  131. //this.$emit('setEnableScroll', true);
  132. },
  133. }
  134. }
  135. </script>
  136. <style lang="less" scoped>
  137. .mix-refresh-content{
  138. display: flex;
  139. flex-direction: column;
  140. position: relative;
  141. }
  142. /* 下拉刷新部分 */
  143. .mix-loading-wrapper{
  144. position: absolute;
  145. left: 0;
  146. top: 0;
  147. transform: translateY(-100%);
  148. display: flex;
  149. justify-content: center;
  150. align-items: center;
  151. width: 100%;
  152. height: 100rpx;
  153. font-size: 24rpx;
  154. .cu-load{
  155. font-size: 36rpx;
  156. }
  157. }
  158. .mix-loading-icon{
  159. width: 70upx;
  160. height: 70upx;
  161. transition: .3s;
  162. }
  163. .mix-loading-icon.ready{
  164. transform: scaleX(1.3);
  165. }
  166. .mix-loading-icon.active{
  167. animation: loading .5s ease-in infinite both alternate;
  168. }
  169. @keyframes loading {
  170. 0% {
  171. transform: translateY(-20upx) scaleX(1);
  172. }
  173. 100% {
  174. transform: translateY(4upx) scaleX(1.3);
  175. }
  176. }
  177. </style>