vuejs實現瀑布流佈局(二)

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

相關文章
相關標籤/搜索