瀑布流布局已然完成,那么剩下的就是另外一个比较大的工程了——无限加载。javascript
以前说了,这个活动项目是基于SUI-Mobile搭建的,因此能够直接使用sui内建组件“无限加载”来实现这个功能。vue
没有真实的数据,全部数据都是本身建立的假数据java
以works.json为例:ios
[ { "id": 1, "src": "http://cued.xunlei.com/demos/publ/img/P_000.jpg", "numbering":"00001", "school":"双语小学", "student":"王伟", "praise":"23", "isDel": true, "delDesc": "图片不符合法律要求", "name": "美美的一天", "todayClk": false, "isPraise": false }, ... ]
一个数组,里面是一个个的对象。ajax
最开始实现的时候,是在methods对象里面定义一个初始化请求函数,一个分页请求函数vue-router
fetchData(fn){ var _this = this; axios.get("./src/assets/data/worksRank.json").then(function (res) { _this.worksList=res.data if (typeof fn =="function") fn(); }) }, loadingMore(){ var _this = this; var loading = false; // 每次加载添加多少条目 var itemsPerLoad = 10, page = 2; // 注册'infinite'事件处理函数 $(document).on('infinite', function() { // 若是正在加载,则退出 if (loading) return; // 设置flag loading = true; // 模拟1s的加载过程,实际项须要调用ajax向后台取数据 // 重置加载flag axios.get('./src/assets/data/worksRank.json', { page: page, val: "" }).then(function (response) { loading = false; //添加判断条件 若是返回的数组的数据小于每页应当加载的数据条数,则表示加载完毕 if (response.data.length < itemsPerLoad) { // 加载完毕,则注销无限加载事件,以防没必要要的加载 $.detachInfiniteScroll($('.infinite-scroll')); // 删除加载提示符 $('.infinite-scroll-preloader').remove(); return; } // 添加新条目 // _this.addWorks(response.data); _this.worksList = _this.worksList.concat(response.data); page++; //容器发生改变,若是是js滚动,须要刷新滚动 $.refreshScroller(); }); }); }
而后在mounted内调用这两个函数,发现很快实现该无限加载的功能了。再继续研究下去,也受到一片文章的启发,其实所谓无限加载,不就是咱们常说的分页么?json
改变思路以下:axios
当页面滑动到底部的时候,仅仅增长页码,而后监听页码的变化,而后调用初始化时候的ajax请求,去请求后台数据。数组
loadingMore(){ var _this = this; // 注册'infinite'事件处理函数 $(document).on('infinite', function() { // 若是正在加载,则退出 if (_this.loading) return; // 设置flag _this.loading = true; // 无限加载,其实就是相似于分页的效果,增长页码 _this.page++; }); },
watch: { page: function () { this.ajaxData(); } }
向后台请求数据,须要带两个参数,一个是页码page,一个是值val,该值是为了搜索功能使用。dom
其余的操做所有放在ajax请求内部操做:
ajaxData(){ axios.get('./src/assets/data/works.json',{ page: this.page, val: this.val }).then(function (response) { this.loading = false; // 为了美观,这里对获取到的推按进行了随机数的处理,实际项目中,不须要额外处理 response.data.forEach(function (item, index) { var num = Math.ceil(Math.random()*162); num = num < 10 ? "00"+num : num < 100 ? "0" + num : num; item.src = item.src.replace(/[\d]+/, num); // 预加载 var img = new Image(); img.src = item.src; }); //添加判断条件 若是返回的数组的数据小于每页应当加载的数据条数,则表示加载完毕 if (response.data.length < this.items) { // 加载完毕,则注销无限加载事件,以防没必要要的加载 $.detachInfiniteScroll($('.infinite-scroll')); // 删除加载提示符 $('.infinite-scroll-preloader').remove(); return; } if (this.page == 1) { this.works = response.data; } else { this.works = this.works.concat(response.data); } // 若是是下拉刷新的话 $.pullToRefreshDone('.pull-to-refresh-content'); }.bind(this)); },
对于返回数据循环操做这一步能够不予关注,我这里主要是为了获取不一样的图片,进行的随机数,实际请求过程当中,每次返回的都是不一样数据,不存在这一过程。
还有一个判断 :
if (this.page == 1) { this.works = response.data; } else { this.works = this.works.concat(response.data); }
这里须要判断当前页码是否为1,若是为1的话,返回的数据直接赋值给works,若是不是1,则在原有值的基础上追加,目的是方便下拉刷新和搜索。
原觉得到这里,已经完全完成工做,可是在屡次测试以后发现,还有一个更大的bug在那呢!
路由跳转以后,必须刷新页面,才能实现新页面的无限加载,发现该问题以后,当即意识到了问题之所在:
因为路由点击以后,并无为document绑定infinite事件,致使跳转以后的页面没法触发infinite事件,就没法实现无限加载。
解决问题的思路在于:在路由跳转页面的时候,关闭以前组件绑定的infinite事件,而在新组件中从新绑定infinite事件。
查询vue-router官方文档,发现“导航钩子”这一说法,共有三个钩子函数:
beforeRouteEnter
beforeRouteUpdate
(2.2 新增)beforeRouteLeave
这里须要用到的是beforeRouteLeave,在路由跳转离开的时候,关闭当前页面注册的“
无限滚动事件”,在新组件mounted的时候从新绑定“
无限滚动事件”,代码修改成:
beforeRouteLeave (to, from, next) { this.page =1; $.detachInfiniteScroll($(".infinite-scroll")); next(true); },
mounted(){ $.init() this.refresh(); this.ajaxData(); this.loadingMore(); $.attachInfiniteScroll($(".infinite-scroll")); },
至此,使用vuejs搭配SUI-Mobile的瀑布流布局真正实现了,其中也遇到了各类槽点,初学vuejs,总得付出点填坑的代价的。