当前位置:   article > 正文

vue 实现上拉加载下拉刷新(思路贼清晰)_div 下拉刷新下拉加载

div 下拉刷新下拉加载


项目需要用到上拉刷新下拉加载 所以自己手动实现了一个 
组件:

  1. <template>
  2. <div class="my-scroll" ref="myScroll" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)">
  3. <div class="scroll-top" :style="{height:top+'px'}">
  4. <div v-if="aspect==2">
  5. <p v-if="state==6">
  6. 下拉刷新
  7. </p>
  8. <p v-if="state==1">
  9. <i><img :src="Load"/></i>
  10. <br/>
  11. 刷新中
  12. </p>
  13. <p v-if="state==2">松开刷新</p>
  14. <p v-if="state==3">
  15. <i><img :src="Load"/></i>
  16. <br/>
  17. 刷新完成
  18. </p>
  19. </div>
  20. </div>
  21. <!-- top -->
  22. <div class="scroll-list" :style="{ transform: 'translate3d(0, ' + top + 'px, 0)'}">
  23. <slot name='scrollList'></slot>
  24. <div class="scroll-bottom">
  25. <div v-if="state==4">加载中</div>
  26. <div v-if="state==5">加载完成</div>
  27. <div v-if="state==7">没有更多</div>
  28. </div>
  29. </div>
  30. </div>
  31. </template>
  32. <script type="text/javascript">
  33. import Load from '../assets/Load.gif'
  34. export default {
  35. name:'myScroll',
  36. props:{
  37. 'page':{
  38. type:Object, //counter:当前页 pageStart:开始页数 pageEnd:结束页数 total:总页数
  39. require:true,
  40. },
  41. 'onRefresh':{ //刷新回调
  42. type:Function,
  43. require:true
  44. },
  45. 'onPull':{ //加载回调
  46. type:Function,
  47. require:true
  48. },
  49. 'getScrollTop':{ //获取滚动条位置
  50. type:Function
  51. },
  52. 'setScrollPage':{ //改变滚动条位置
  53. type:Function
  54. },
  55. },
  56. data(){
  57. return {
  58. Load,
  59. pageX:0,
  60. pageY:0,
  61. state:0,
  62. scrollPosition:0,
  63. myScroll:null,
  64. myScrollList:null,
  65. top:0,
  66. aspect:0, //1:向下 2:向上
  67. listHeight:0,
  68. }
  69. },
  70. created(){
  71. this.$root.$on('setState', (index) => { //修改状态
  72. this.state = index
  73. if(index == 5||index == 3){
  74. setTimeout(()=>{
  75. this.state = 0
  76. this.top = 0
  77. },300)
  78. }
  79. })
  80. this.$root.$on('ScrollTop',(top)=>{ //修改滚动条位置
  81. this.myScroll.scrollTop = top
  82. })
  83. },
  84. methods:{
  85. touchStart(e){ //触摸事件
  86. this.pageX = e.targetTouches[0].pageX
  87. this.pageY = e.targetTouches[0].pageY
  88. },
  89. touchMove(e){ //触摸滑动事件
  90. this.scrollPosition = this.myScroll.scrollTop //获取滚动条位置
  91. if(e.targetTouches[0].pageY>this.pageY){ //向上滑动
  92. this.aspect = 2
  93. if(this.myScroll.scrollTop==0){
  94. let diff = e.targetTouches[0].pageY - this.pageY - this.scrollPosition
  95. this.top = Math.pow(diff, 0.9)
  96. let ranget = diff/document.body.clientHeight*100 //计算在屏幕上滑动了多少
  97. if(ranget > 20){
  98. this.state = 2
  99. }else if(ranget < 15){
  100. this.state = 6
  101. }
  102. e.preventDefault()
  103. }
  104. }else if(this.state!=4){ //向上滑动
  105. this.aspect = 1
  106. }
  107. },
  108. touchEnd(e){
  109. if(this.aspect == 2&&this.state == 2||this.state == 1){ //上拉处理
  110. this.top = 100
  111. this.state = 1
  112. this.topCallback()
  113. }else if(this.aspect == 2){
  114. this.state = 0
  115. this.top = 0
  116. }
  117. },
  118. topCallback(){ //刷新回调
  119. this.onRefresh(this.state)
  120. },
  121. bottomCallback(){ //加载回调
  122. this.state = 4
  123. this.onPull(this.state)
  124. }
  125. },
  126. mounted(){
  127. this.myScroll = this.$refs.myScroll //获取滑条dom
  128. this.myScrollList = this.myScroll.children[1] //获取列表dom
  129. this.myScroll.addEventListener('scroll',(e)=>{ //监听滚动条事件
  130. let listHeight = this.myScrollList.offsetHeight //列表总高度
  131. let listScrollTop = e.target.scrollTop + this.myScroll.offsetHeight //当前滚动条位置
  132. if(this.state == 0&&listHeight-listScrollTop < 100){
  133. this.bottomCallback()
  134. }
  135. if(this.getScrollTop)this.getScrollTop(e.target.scrollTop) //返回X,Y
  136. })
  137. }
  138. }
  139. </script>
  140. <style lang="scss" scoped>
  141. .my-scroll{
  142. color: #fff;
  143. max-width: 100%;
  144. max-height: 100%;
  145. height: 100%;
  146. overflow:hidden;
  147. overflow-y: scroll;
  148. -webkit-overflow-scrolling: touch;
  149. will-change: transform;
  150. transition: all 450ms;
  151. backface-visibility: hidden;
  152. perspective: 1000;
  153. position: relative;
  154. .scroll-top{
  155. text-align: center;
  156. display:flex;
  157. position:absolute;
  158. top:0;
  159. left:0;
  160. width:100%;
  161. div{
  162. display:flex;
  163. height:auto;
  164. width:100%;
  165. justify-content: center;
  166. align-items:center;
  167. flex-wrap: wrap;
  168. i{
  169. flex:1 0 100%;
  170. display:block;
  171. height: 0.4rem;
  172. }
  173. img{
  174. width:0.8rem;
  175. }
  176. p{
  177. flex:1 0 100%;
  178. }
  179. }
  180. }
  181. .scroll-list{
  182. overflow:hidden;
  183. }
  184. .scroll-bottom{
  185. text-align: center;
  186. line-height: 40px;
  187. }
  188. }
  189. </style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194

使用:

  1. <template>
  2. <div class="index">
  3. <my-scroll :page="page" :on-refresh="onRefresh" :on-pull="onPull">
  4. <div slot="scrollList">
  5. <ul>
  6. <li v-for="(x,index) in list" :key="index">列表</li>
  7. </ul>
  8. </div>
  9. </my-scroll>
  10. </div>
  11. </template>
  12. <script type="text/javascript">
  13. import myScroll from '@/components/myScroll.vue'
  14. export default {
  15. data(){
  16. return{
  17. list:[],
  18. page:{
  19. counter:1,
  20. pageStart:1,
  21. pageEnd:1,
  22. total:10
  23. },
  24. }
  25. },
  26. methods:{
  27. onRefresh(mun){ //刷新回调
  28. setTimeout(()=>{
  29. this.$root.$emit('setState',3)
  30. },500)
  31. },
  32. onPull(mun){ //加载回调
  33. if(this.page.counter<=this.page.total){
  34. setTimeout(()=>{
  35. this.page.counter++
  36. this.$root.$emit('setState',5)
  37. for(let i=0;i<10;i++){
  38. this.listdata.push({})
  39. }
  40. },500)
  41. }else{
  42. this.$root.$emit('setState',7)
  43. }
  44. },
  45. },
  46. components:{
  47. myScroll
  48. },
  49. created(){
  50. },
  51. mounted(){
  52. for(let i=0;i<1*50;i++){
  53. this.list.push({})
  54. }
  55. },
  56. }
  57. </script>
  58. <style lang="scss" scoped>
  59. .index{
  60. }
  61. </style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

上拉刷新实现思路: 
1.通过touchstart获取用户第一次点击的坐标 
2.通过touchmove 判断向上滑动还是向下 
4.判断列表的滚动条是否在最顶部 
5.然后判断在这个屏幕滑动的比例 进行状态显示 
下拉加载实现思路: 
1.通过判断滚动条位置实现下拉加载

样式: 
这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28027903/article/details/80242714
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/1009033
推荐阅读
相关标签
  

闽ICP备14008679号