当前位置:   article > 正文

【Vue学习总结】22.使用Mint UI的infinite-scroll实现上拉分页加载_infinite-scroll-distance

infinite-scroll-distance

接上篇《21.Vue-UI框架之Mint UI的使用

上一篇我们讲解了Vue的UI框架Mint UI的使用,本篇我们来通过Mint UI提供的infinite-scroll组件结合api接口实现一个上拉分页加载更多的功能。
本系列博文使用的Vue版本:2.6.11
Mint UI 中文开发文档:https://www.w3cschool.cn/mintui/

一、infinite-scroll介绍

实现上拉分页加载更多的功能,需要用到Mint UI提供的infinite-scroll(无限滚动)组件。下面我们简单介绍一下该组件的使用。

infinite-scroll为Mint UI的JS组件之一,它能提供一个无限滚动的指令,即我们会初始加载一部分数据,当你拖动列表下拉时,会触发动态加载,一段简单的加载动画后,会将新加载的列表拼接在已显示的列表下,相当于我只要往下拉动列表,就会无限的加载出数据,不拉动就不加载。效果如下:

例子
为 HTML 元素添加 v-infinite-scroll 指令即可使用无限滚动。滚动该元素,当其底部与被滚动元素底部的距离小于给定的阈值(通过 infinite-scroll-distance 设置)时,绑定到 v-infinite-scroll 指令的方法就会被触发。

  1. <ul
  2.   v-infinite-scroll="loadMore"
  3.   infinite-scroll-disabled="loading"
  4.   infinite-scroll-distance="10">
  5.   <li v-for="item in list">{{ item }}</li>
  6. </ul>

这里的loadMore方法,就是为list数组再加增加10个元素:

  1. loadMore() {
  2.   this.loading = true;//在加载数据的时候,暂时关闭滚动加载触发
  3.   setTimeout(() => {
  4.     let last = this.list[this.list.length - 1];
  5.     for (let i = 1; i <= 10; i++) {
  6.       this.list.push(last + i);
  7.     }
  8.     this.loading = false;//数据加载完毕后,再次开启滚动加载触发
  9.   }, 2500);
  10. }

其中的“infinite-scroll-disabled”、“infinite-scroll-distance”的含义,见API:

这样,我们如果想实现上拉分页的效果,其实只要引入infinite-scroll组件,并且实现“v-infinite-scroll”的加载数据方法即可。
理论已经有了,下面动手来实现它吧。

二、实现上拉分页效果

我们清理一下原来的MintUI.vue页面,先引入infinite-scroll组件,写一个简单的触发方法,看看能不能触发:

  1. <template>
  2.   <div id="MintUI">
  3.     <h1>{{msg}}</h1>
  4.     <ul
  5.       v-infinite-scroll="loadMore"
  6.       infinite-scroll-disabled="loading"
  7.       infinite-scroll-distance="10">
  8.       <li v-for="item in list" :key="item">{{ item }}</li>
  9.     </ul>
  10.   </div>
  11. </template>
  12.  
  13. <script>
  14. export default {
  15.   name: 'MintUI',
  16.   data () {
  17.       return {
  18.         msg: 'Mint-UI',
  19.         list:[]
  20.       }
  21.   },
  22.   methods:{
  23.     loadMore(){
  24.       console.log(111111111111111);
  25.     }
  26.   }
  27. }
  28. </script>
  29.  
  30. <style scoped>
  31. </style>

这里我们期望的效果就是,上拉触发loadMore方法,实验效果:

我们仿照官方网站的例子,写一个10行显示的效果,需要实现两点,第一点就是每次上拉扩充list数组,第二就是每一行按照“infinite-scroll-distance”参数的要求,每隔10个像素触发加载,所以一行至少是1个像素,要优化一下行间距,代码如下:

  1. <template>
  2.   <div id="MintUI">
  3.     <h1>{{msg}}</h1>
  4.     <ul
  5.       v-infinite-scroll="loadMore"
  6.       infinite-scroll-disabled="loading"
  7.       infinite-scroll-distance="10" class="list">
  8.       <li v-for="item in list" :key="item">{{ item }}</li>
  9.     </ul>
  10.   </div>
  11. </template>
  12.  
  13. <script>
  14. export default {
  15.   name: 'MintUI',
  16.   data () {
  17.       return {
  18.         msg: 'Mint-UI',
  19.         list:[],
  20.         loading:false,
  21.         j:0
  22.       }
  23.   },
  24.   methods:{
  25.     loadMore(){
  26.       this.loading = true;
  27.       console.log(111111111111111);
  28.       for(var i=0;i<20;i++,this.j++){
  29.           this.list.push("第"+this.j+"条");
  30.       }
  31.       this.loading = false;
  32.     }
  33.   }
  34. }
  35. </script>
  36.  
  37. <style scoped>
  38.   .list li{
  39.      height: 3.4rem;
  40.      line-height: 3.4rem;
  41.      border-bottom: 1px solid #000;
  42.      font-size: 1.6rem;
  43.   }
  44. </style>

效果:

可以看到满10条数据,就执行一次加载方法。
按照上面的写法,我们可以进行动态数据的填充,我们通过接口来扩充list数组,来实现加载真实网络API接口的效果。

三、通过API数据接口实现上拉分页

上面是通过模拟数据实现的上拉分页,这里我们通过访问真实的API接口,获取数据,动态加载到页面上。
这里我们使用vue-resource来实现HTTP请求。

我们改造一下loadMore方法,请求网络数据。

  1. <template>
  2.   <div id="MintUI">
  3.     <h1>{{msg}}</h1>
  4.     <ul
  5.       v-infinite-scroll="loadMore"
  6.       infinite-scroll-disabled="loading"
  7.       infinite-scroll-distance="10" class="list">
  8.       <li v-for="item in list" :key="item">{{ item.title }}</li>
  9.     </ul>
  10.   </div>
  11. </template>
  12.  
  13. <script>
  14. export default {
  15.   name: 'MintUI',
  16.   data () {
  17.       return {
  18.         msg: 'Mint-UI',
  19.         list:[],
  20.         loading:false,
  21.         page:1 //默认第一次请求第一页
  22.       }
  23.   },
  24.   methods:{
  25.     loadMore(){
  26.       this.loading = true;
  27.       this.requestData();
  28.       this.loading = false;
  29.     },
  30.     requestData(){
  31.         var api_url="http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page="+this.page;
  32.         var that  = this;//这里重新指定this 是因为在 then的内部不能使用Vue的实例化的this, 因为在内部 this 没有被绑定。
  33.         //jsonp支持跨域请求,后台api接口也需要支持
  34.         this.$http.jsonp(api_url).then(
  35.             function(response){
  36.                that.list=that.list.concat(response.body.result);//数组拼接
  37.                this.page+=1;//下次加载下一页
  38.             },function(err){
  39.                console.log(err);
  40.             }
  41.         );
  42.     }
  43.   }
  44. }
  45. </script>
  46.  
  47. <style scoped>
  48.   .list li{
  49.      height: 3.4rem;
  50.      line-height: 3.4rem;
  51.      border-bottom: 1px solid #000;
  52.      font-size: 1.6rem;
  53.   }
  54. </style>

这里我们添加了新闻列表的API接口请求,每次请求1页的数据。效果:

这里我们需要注意一个问题,因为我们请求新闻是异步请求,有可能出现在新闻的网络请求没有加载完,快速拉动列表的时候,又触发了新的加载,此时page还没来得及更新,会出现两次加载同一个数据的情况:

如何解决这个问题呢?很简单,我们在请求完成之前,不允许触发动态加载的方法,即我们将“loading”这个请求数据的开关,在加载完成之后再打开:

  1. methods:{
  2.     loadMore(){
  3.       this.requestData();
  4.     },
  5.     requestData(){
  6.         this.loading = true;//关闭触发请求的开关
  7.         var api_url="http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page="+this.page;
  8.         var that  = this;//这里重新指定this 是因为在 then的内部不能使用Vue的实例化的this, 因为在内部 this 没有被绑定。
  9.         //jsonp支持跨域请求,后台api接口也需要支持
  10.         this.$http.jsonp(api_url).then(
  11.             function(response){
  12.                that.list=that.list.concat(response.body.result);//数组拼接
  13.                this.page+=1;//下次加载下一页
  14.                if(response.body.result.length<20){//当请求数据是最后一页时
  15.                   this.loading = true;//最后一页时,关闭触发请求的开关
  16.                   that.list=that.list.concat({title:'没有数据了,已经到底......'});//到最后给用户一个提示
  17.                }else{
  18.                   //当请求数据不是最后一页时
  19.                   this.loading = false;//加载完成后,打开触发请求的开关
  20.                }
  21.             },function(err){
  22.                console.log(err);
  23.             }
  24.         );
  25.     }
  26. }

这里还有一个细节,就是处理最后一页的问题,就是当拉到没有数据的时候,就不允许再拉了。
效果:

最后,为了让用户感觉有上拉的加载效果,我们在上拉的时候,显示正在加载的信息提示,这里在<ul>列表最后新增一个<div>标签,放置一个加载信息(也可以配上转圈的动画):

  1. <template>
  2.   <div id="MintUI">
  3.     <h1>{{msg}}</h1>
  4.     <ul
  5.       v-infinite-scroll="loadMore"
  6.       infinite-scroll-disabled="loading"
  7.       infinite-scroll-distance="10" class="list">
  8.       <li v-for="item in list" :key="item">{{ item.title }}</li>
  9.     </ul>
  10.     <div>{{loadMsg}}</div>
  11.   </div>
  12. </template>
  13.  
  14. <script>
  15. export default {
  16.   name: 'MintUI',
  17.   data () {
  18.       return {
  19.         msg: 'Mint-UI',
  20.         list:[],
  21.         loading:false,
  22.         page:1, //默认第一次请求第一页
  23.         loadMsg:'加载中...'//加载信息
  24.       }
  25.   },
  26.   methods:{
  27.     loadMore(){
  28.       this.requestData();
  29.     },
  30.     requestData(){
  31.         this.loading = true;//关闭触发请求的开关
  32.         var api_url="http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page="+this.page;
  33.         var that  = this;//这里重新指定this 是因为在 then的内部不能使用Vue的实例化的this, 因为在内部 this 没有被绑定。
  34.         //jsonp支持跨域请求,后台api接口也需要支持
  35.         this.$http.jsonp(api_url).then(
  36.             function(response){
  37.                that.list=that.list.concat(response.body.result);//数组拼接
  38.                this.page+=1;//下次加载下一页
  39.                if(response.body.result.length<20){//当请求数据是最后一页时
  40.                   this.loading = true;//最后一页时,关闭触发请求的开关
  41.                   this.loadMsg = '没有数据了,已经到底......';//修改加载信息,给用户一个提示
  42.                }else{
  43.                   //当请求数据不是最后一页时
  44.                   this.loading = false;//加载完成后,打开触发请求的开关
  45.                }
  46.             },function(err){
  47.                console.log(err);
  48.             }
  49.         );
  50.     }
  51.   }
  52. }
  53. </script>
  54.  
  55. <style scoped>
  56.   .list li{
  57.      height: 3.4rem;
  58.      line-height: 3.4rem;
  59.      border-bottom: 1px solid #000;
  60.      font-size: 1.6rem;
  61.   }
  62. </style>

加载时效果:

加载到最后效果:

注:由于没有处理样式,很丑,见谅,有条件的童鞋可以进行相应的优化。

以上就是使用infinite-scroll实现上拉分页加载的全部内容。


参考:
《IT营:itying.com-2018年Vue2.x 5小时入门视频教程》

转载请注明出处:https://blog.csdn.net/acmman/article/details/111810692

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/698648
推荐阅读
  

闽ICP备14008679号