完整的Infinite scroll无限滚动指令,下拉刷新demo / loadmore【同步官方文档同步】
vue 2017-09-30 09:37:09

问题:页面刷新后/初始加载正常,第二次进入页面,无限滚动容器则显示空白?

答案:无限滚动的容器是固定的,如果上面的ui图占满了窗口,则不再执行loadmore方法。

 
 
 

同步官方文档:

2017.11.16 不需要下拉刷新,仅无限滚动:

XML/HTML Code复制内容到剪贴板
  1. <template>      
  2.     <ul v-infinite-scroll="loadMore" infinite-scroll-disabled="loading" infinite-scroll-immediate-check="false" infinite-scroll-distance="10">      
  3.       
  4.         <!-- 开始循环数据列表 -->      
  5.         <div class="class-item clear" v-for="item in teachPlanLibrary">      
  6.             <input type="checkbox" class="fl checkbox" :value="item.planId" v-model="selectedPlanIds">      
  7.             <div class="fl">{{item.planName}}</div>      
  8.             <router-link :to="'/course/edit-plan/'+item.planId" tag="div" class="fr class-icon"></router-link>      
  9.         </div>      
  10.       
  11.     </ul>      
  12. </template>      

这里的infinite-scroll-immediate-check在个数比较少的时候,会比较有用,默认是true,接口请求至撑满整个容器,如果个数少,肯定撑不满,所以默认不需要它撑满,设为false

 

JavaScript Code复制内容到剪贴板
  1. <script>      
  2.     import { Loadmore } from 'mint-ui' //完整引入mint ui 可以省略不写      
  3.       
  4.     export default {      
  5.         name: 'procution-support',      
  6.         data() {      
  7.             return {      
  8.                 searchFilter: {      
  9.                     pageNo: 1,      
  10.                     pageSize: 15,      
  11.                     user_id: this.$store.state.common.userId      
  12.                 },  
  13.                 teachPlanLibrary:[],  
  14.                 loading: false// 是否可以继续触发无限滚动列表中loading是否显示      
  15.             }      
  16.         },      
  17.         mounted() {      
  18.             this.init()      
  19.         },      
  20.         methods: {      
  21.             init() {     
  22.                 //初始化载入列表      
  23.                 this.searchFilter.pageNo = 1;      
  24.                 this.loadList(this.searchFilter);      
  25.             },      
  26.             // 加载更多        
  27.             loadMore() {      
  28.                 if(this.loading) {      
  29.                     return false;      
  30.                 };      
  31.       
  32.                 this.loading = true;      
  33.                 this.searchFilter.pageNo = parseInt(this.searchFilter.pageNo) + 1;  //每次加载,页码+1      
  34.                 this.loadList(this.searchFilter);      
  35.       
  36.             },      
  37.             loadList(params) {      
  38.                 // 查询数据      
  39.                 this.request.post(this.$store.state.course.api.getTeachPlanList, params).then(response => {      
  40.       
  41.                     this.$indicator.close(); //关闭loading      
  42.                     let res = response.data;      
  43.                     if(res.code == 0) {      
  44.                         if(!res.data) {      
  45.                             return false;      
  46.                         }      
  47.                         let data = JSON.parse(res.data.gsonStr); // 返回的结果数组      
  48.                         let total = res.data.tot; // 返回的总条数      
  49.       
  50.                         this.loading = false;      
  51.                         this.teachPlanLibrary = this.teachPlanLibrary.concat(data);      
  52.                         this.isHaveMore(total); //根据总条数与已加载条数判断是否一致来判断是否有更多数据      
  53.       
  54.                     } else {      
  55.                         this.$toast("获取教学计划列表失败,请重试");      
  56.                     }      
  57.                     // success callback      
  58.                 }, response => {      
  59.                     // error callback            
  60.                 })      
  61.       
  62.             },      
  63.             isHaveMore(total) {     
  64.                 // 是否还有下一页   
  65.                 if(total == this.teachPlanLibrary.length) {      
  66.                     this.loading = true//不再触发无限加载        
  67.                 }  
  68.             },      
  69.         }      
  70.     }      
  71. </script>      

 是否还有下一页,或者条件是 total <= 也可以 

 

 

 


 
 

根据官方文档组建 无限滚动 + 下拉刷新的完整 源码:

XML/HTML Code复制内容到剪贴板
  1.         <!--  
  2.         mt-loadmore 下拉刷新(额外组件)  
  3.         :bottom-method="loadBottom" 上拉刷新 这个方法注释了   
  4.         allLoaded: 是否可以上拉属性,false可以,true为禁止  
  5.         top-distance 触发 topMethod 的下拉距离  
  6.         max-distance 手指下拉的最大距离  
  7.         -->  
  8.         <mt-loadmore :top-method="loadTop" :bottom-all-loaded="allLoaded" ref="loadmore" @top-status-change="handleTopChange" :top-distance="topDistance" :max-distance="100">  
  9.   
  10.             <!--  
  11.                         自定义下拉刷新html模板(可删) 标签设置 slot 属性为 top,类名为 mint-loadmore-top  
  12.             pull:组件已经被按下,但按下的距离未达到 topDistance,此时释放不会触发 top-method,列表会回到初始位置  
  13.             drop:按下的距离不小于 topDistance,此时释放会触发 top-method  
  14.             loading:组件已被释放,top-method 正在执行 每当组件的状态发生变化时,loadmore 都会触发 top-status-change 所绑定的方法名称,如handleTopChange  
  15.              -->  
  16.             <div slot="top" class="mint-loadmore-top">  
  17.                 <span v-show="topStatus === 'pull'" :class="{ 'rotate': topStatus === 'drop' }"></span>  
  18.                 <span v-show="topStatus === 'loading'">Loading...</span>  
  19.                 <span v-show="topStatus === 'drop'"><i class="icon iconfont"></i> 刷新成功</span>  
  20.             </div>  
  21.   
  22.             <!-- 单词列表 -->  
  23.             <ul v-infinite-scroll="loadMore" infinite-scroll-disabled="loading" infinite-scroll-distance="10">  
  24.   
  25.                 <li v-for="item in pageList" class="page-infinite-listitem">  
  26.   
  27.                     <label class="mint-checklist-label">  
  28.                         <div class="text" @click="playMp3(item.data.attachment_en)">  
  29.                                 <span class="title">{{item.title}}</span>  
  30.                             <br>  
  31.                             <div class="show-word show-play">  
  32.                                 <span class="play"><i class="icon iconfont"></i></span>  
  33.                                 <span class="ptitle">{{item.data.word}}</span>    
  34.                             </div>  
  35.                         </div>  
  36.                         <img @click="playMp3(item.data.attachment_zh)" v-lazy="item.cover" class="pic">  
  37.                         <!--<router-link :to="'/detail/' + item.id"><img v-lazy="item.cover" class="pic"></router-link>-->  
  38.                     </label>  
  39.                 </li>  
  40.             </ul>  
  41.   
  42.             <div class="text-center">  
  43.                 <mt-spinner type="fading-circle" v-if="loading" v-show="!loading" class="page-infinite-loading"></mt-spinner>  
  44.             </div>  
  45.   
  46.         </mt-loadmore>  
  47.   
  48.   
  49.   
  50. <script>  
  51.     export default {  
  52.         data: function() {  
  53.             return {  
  54.                 cid: this.$route.params.cid,  
  55.                 searchCondition: { //分页属性  
  56.                     cid: this.$route.params.cid,  
  57.                     pageNo: 0,  
  58.                     pageSize: 15  
  59.                 },  
  60.                 pageList: [],  
  61.                 allLoaded: false, // 是否可以上拉属性,false可以上拉,true为禁止上拉,就是不让往上划加载数据了  
  62.                 scrollMode: "auto", // 移动端弹性滚动效果,touch为弹性滚动,auto是非弹性滚动  
  63.                 loading: false, // 无限滚动列表中loading是否显示  
  64.                 topStatus: "", // 下拉刷新顶部状态  
  65.                 topDistance:70, // 默认就是距离70  
  66.             }  
  67.         },  
  68.         mounted() {  
  69.             this.init(); //初次访问重新设置标题名  
  70.         },  
  71.         methods: {  
  72.             init() {  
  73.                 this.$store.commit('common/changePageTitle', "单词学习");  
  74.             },  
  75.             //加载列表,写入全局状态,ifRefresh是否为刷新  
  76.             loadList(searchCondition, ifRefresh) {  
  77.   
  78.                 // 如果是刷新就从第一页开始重新请求并加载列表  
  79.                 if(ifRefresh) {  
  80.   
  81.                     this.$http.get(this.$store.state.common.api.getListData, {  
  82.                         params: searchCondition  
  83.                     }).then((response) => {  
  84.   
  85.                         let result = response.data;  
  86.                         let param = {  
  87.                             cid: this.cid,  
  88.                             pageNo: searchCondition.pageNo,  
  89.                             data: result  
  90.                         };  
  91.                         this.$store.commit("list/savePageData", param);  
  92.   
  93.                         this.loading = false;  
  94.                         this.pageList = result.items;  
  95.                         this.isHaveMore(result._links.next);  
  96.                     });  
  97.   
  98.                 } else {  
  99.   
  100.                     // 如果有缓存数据  
  101.                     if(this.$store.state.list.pageListSaveByCid[this.cid] && this.$store.state.list.pageListSaveByCid[this.cid][searchCondition.pageNo]) {  
  102.                         //                  console.log(this.$store.state.list.pageListSaveByCid[this.cid][searchCondition.pageNo]);  
  103.                         let result = this.$store.state.list.pageListSaveByCid[this.cid][searchCondition.pageNo];  
  104.                         this.loading = false;  
  105.                         thisthis.pageList = this.pageList.concat(result.items);  
  106.                         this.isHaveMore(result._links.next);  
  107.   
  108.                     } else {  
  109.   
  110.                         this.$http.get(this.$store.state.common.api.getListData, {  
  111.                             params: searchCondition  
  112.                         }).then((response) => {  
  113.   
  114.                             let result = response.data;  
  115.                             let param = {  
  116.                                 cid: this.cid,  
  117.                                 pageNo: searchCondition.pageNo,  
  118.                                 data: result  
  119.                             };  
  120.                             this.$store.commit("list/savePageData", param);  
  121.   
  122.                             this.loading = false;  
  123.                             thisthis.pageList = this.pageList.concat(result.items);  
  124.                             this.isHaveMore(result._links.next);  
  125.                         });  
  126.                     }  
  127.   
  128.                 }  
  129.   
  130.             },  
  131.             // 加载更多  
  132.             loadMore() {  
  133. //              if(this.loading) {  
  134. //                  return false;  
  135. //              };  
  136.                 console.log(11);  
  137.                 this.loading = true;  
  138.                 this.searchCondition.pageNo = parseInt(this.searchCondition.pageNo) + 1;  
  139.                 this.loadList(this.searchCondition);  
  140.   
  141.             },  
  142.               
  143.             isHaveMore(isHaveMore) {  
  144.                 // 是否还有下一页,如果没有就禁止上拉刷新  
  145.                 this.allLoaded = true; //true是禁止上拉加载  
  146.                 if(isHaveMore) {  
  147.                     this.allLoaded = false;  
  148.                 } else {  
  149.                     this.loading = true; //不再触发无限加载  
  150.                 }  
  151.             },  
  152.             //下拉刷新,组件提供的下拉触发方法  
  153.             loadTop() {  
  154.                 this.searchCondition.pageNo = 1;  
  155.                 this.loadList(this.searchCondition, true);  
  156.                 this.$refs.loadmore.onTopLoaded(); // 固定方法,查询完要调用一次,用于重新定位  
  157.             },  
  158.             handleTopChange(status) {  
  159.                 this.topStatus = status;  
  160.             },  
  161.         }  
  162.     }  
  163. </script>  
  164. </script>  

 

 vuex的list module:

JavaScript Code复制内容到剪贴板
  1. import Vue from 'vue'  
  2. import axios from 'axios'  
  3. import { Toast } from 'mint-ui'  
  4. import { Indicator } from "mint-ui"  
  5.   
  6. // 首先声明一个状态 state  
  7. const state = {  
  8.     pageListSaveByCid:[],// 按照cid的列表缓存列表数据  
  9. }  
  10.   
  11. // 更新状态  
  12. const mutations = {  
  13.       
  14.     savePageData(state,params){  
  15.         let cid = params.cid,  
  16.             pageNo = params.pageNo,  
  17.             data = params.data;  
  18.         state.pageListSaveByCid[cid] = state.pageListSaveByCid[cid]?state.pageListSaveByCid[cid]:[];  
  19.         state.pageListSaveByCid[cid][pageNo] = data;  
  20.     }  
  21.       
  22. }  
  23.   
  24. // 然后给 actions 注册一个事件处理函数,当这个函数被触发时,将状态提交到 mutaions中处理  
  25. const actions = {  
  26.       
  27. }  
  28.   
  29. // 获取状态信息  
  30. const getter = {  
  31.     showState(state) {  
  32.         console.log(state.msg)  
  33.     }  
  34. }  
  35.   
  36. export default {  
  37.     namespaced: true,  
  38.     state,  
  39.     mutations,  
  40.     actions,  
  41.     getter,  
  42. }  

 


 

网上copy的,使用后也是正常的:

XML/HTML Code复制内容到剪贴板
  1. <template>  
  2.     <div class="List" :style="{'-webkit-overflow-scrolling': scrollMode}">  
  3.         <h1>{{ msg }}  </h1>  
  4.         <p>接收路由参数:{{ $route.params.cid }}</p>  
  5.   
  6.         <v-loadmore :top-method="loadTop" :bottom-all-loaded="allLoaded" :auto-fill="false" ref="loadmore" @top-status-change="handleTopChange" :top-distance=50 class="page-infinite-wrapper">  
  7.   
  8.             <!--  
  9.             自定义下拉刷新html模板 标签设置 slot 属性为 top,类名为 mint-loadmore-top  
  10.             pull:组件已经被按下,但按下的距离未达到 topDistance,此时释放不会触发 top-method,列表会回到初始位置  
  11.             drop:按下的距离不小于 topDistance,此时释放会触发 top-method  
  12.             loading:组件已被释放,top-method 正在执行 每当组件的状态发生变化时,loadmore 都会触发 top-status-change 所绑定的方法名称,如handleTopChange  
  13.              -->  
  14.             <div slot="top" class="mint-loadmore-top">  
  15.                 <span v-show="topStatus === 'pull'" :class="{ 'rotate': topStatus === 'drop' }"></span>  
  16.                 <span v-show="topStatus === 'loading'">Loading...</span>  
  17.                 <span v-show="topStatus === 'drop'"><i class="icon iconfont"></i> 刷新成功</span>  
  18.             </div>  
  19.   
  20.             <ul v-infinite-scroll="more" infinite-scroll-disabled="loading" infinite-scroll-distance="10" class="page-infinite-list">  
  21.                 <li v-for="item in pageList" class="page-infinite-listitem">{{ item.title }}</li>  
  22.             </ul>  
  23.   
  24.             <div class="text-center"><mt-spinner type="fading-circle" v-if="showLoading" class="page-infinite-loading"></mt-spinner></div>  
  25.   
  26.         </v-loadmore>  
  27.   
  28.     </div>  
  29. </template>  
  30.   
  31. <script>  
  32.     import {Loadmore} from 'mint-ui';  
  33.     import {Indicator} from 'mint-ui'  
  34.   
  35.     export default {  
  36.         data:function() {  
  37.             return {  
  38.                 msg: '单词学习',  
  39.                 searchCondition:{  //分页属性  
  40.                     cid: this.$route.params.cid,  
  41.                     pageNo:"1",  
  42.                     pageSize:"8"  
  43.                 },  
  44.                 pageList:[],  
  45.                 allLoaded: false, //是否可以上拉属性,false可以上拉,true为禁止上拉,就是不让往上划加载数据了  
  46.                 scrollMode:"auto", //移动端弹性滚动效果,touch为弹性滚动,auto是非弹性滚动  
  47.                 topStatus: '',  
  48.                 showLoading:false  
  49.             }  
  50.         },  
  51.         components: {  
  52.             'v-loadmore':Loadmore  // 为组件起别名,vue转换template标签时不会区分大小写,例如:loadMore这种标签转换完就会变成loadmore,容易出现一些匹配问题  
  53.             // 推荐应用组件时用a-b形式起名  
  54.         },  
  55.         mounted(){  
  56.             this.init();          //初次访问重新设置标题名  
  57.             this.loadPageList();  //初次访问查询列表
  58.         },  
  59.         methods: {  
  60.             init () {  
  61.                 this.$store.commit('changePageTitle', '学习列表');  
  62.             },  
  63.             loadTop() { //组件提供的下拉触发方法  
  64.                 //下拉刷新  
  65.                 this.loadPageList();  
  66.                 this.$refs.loadmore.onTopLoaded();// 固定方法,查询完要调用一次,用于重新定位  
  67.             },  
  68.             loadPageList (){  
  69.   
  70.                 this.searchCondition.pageNo = 1;  
  71.                 this.loading = false;  
  72.                 // 查询数据  
  73.                 this.$http.get('http://demo996.liqinwl.com/api/v1/article/index', {  
  74.                     params: this.searchCondition  
  75.                 }).then((response) => {  
  76.   
  77.                     // 是否还有下一页,加个方法判断,没有下一页要禁止上拉  
  78.                     this.isHaveMore(response.data._links.next);  
  79.                     this.pageList = response.data.items;  
  80.   
  81.                     this.$nextTick(function () {  
  82.                         // 原意是DOM更新循环结束时调用延迟回调函数,大意就是DOM元素在因为某些原因要进行修改就在这里写,要在修改某些数据后才能写,  
  83.                         // 这里之所以加是因为有个坑,iphone在使用-webkit-overflow-scrolling属性,就是移动端弹性滚动效果时会屏蔽loadmore的上拉加载效果,  
  84.                         // 花了好久才解决这个问题,就是用这个函数,意思就是先设置属性为auto,正常滑动,加载完数据后改成弹性滑动,安卓没有这个问题,移动端弹性滑动体验会更好  
  85.                         this.scrollMode = "touch";  
  86.                     });  
  87.                 });  
  88.             },  
  89.             more (){  
  90. //                console.log("是否继续加载:" + this.loading);  
  91.                 if(this.loading){  
  92.                     return false;  
  93.                 };  
  94.                 this.showLoading = true; /* 在底部会有loading的图标则去掉弹出loading层 */  
  95.                 // 分页查询  
  96.                 this.searchCondition.pageNo = parseInt(this.searchCondition.pageNo) + 1;  
  97.                 this.$http.get('http://demo996.liqinwl.com/api/v1/article/index', {  
  98.                     params: this.searchCondition  
  99.                 }).then((response) => {  
  100.   
  101.                     /* 多加一层判断,如果手速下拉的比较快,上面的中断会失效 */  
  102.                     if(this.loading){  
  103.                         this.showLoading = false;  
  104.                         return false;  
  105.                     };  
  106.   
  107.                     thisthis.pageList = this.pageList.concat(response.data.items);  
  108.                     this.isHaveMore(response.data._links.next);  
  109.                 });  
  110.             },  
  111.             isHaveMore(isHaveMore){  
  112.                 // 是否还有下一页,如果没有就禁止上拉刷新  
  113.                 this.allLoaded = true; //true是禁止上拉加载  
  114.                 if(isHaveMore){  
  115.                     this.allLoaded = false;  
  116.                 }else{  
  117.                     this.loading = true;        //不再触发无限加载  
  118.                     this.showLoading = false;  
  119.                 }  
  120.             },  
  121.             handleTopChange(status) {  
  122.                 this.topStatus = status;  
  123.             },  
  124.         }  
  125.     }  
  126.   
  127. </script>  

 

本文来自于:http://www.yoyo88.cn/study/vue/163.html

Powered by yoyo苏ICP备15045725号