瀑布流佈局已然完成,那麼剩下的就是另外一個比較大的工程了——無限加載。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,總得付出點填坑的代價的。