Vue踩坑之旅(四)—— 自定義指令實現滾動加載

這幾天在作商城首頁的商品列表,商品卡片的數量不少,若是一次性加載那麼多,加載較慢,並且用戶體驗很差。因此使用鼠標無限滾動加載效果更好。 實現滾動加載的方式有不少,有現成的組件 InfiniteScroll,可是一些非主流瀏覽器沒法觸發,仍是本身動手寫一寫吧。javascript

實現滾動加載的核心:滾動條高度 + 瀏覽器窗口高度 >= 內容高度 - 閾值html

  • document.body.scrollTop 滾動條滾動的距離 (這個有兼容性問題,兼容性寫法)
    let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
  • window.innerHeight 瀏覽器窗口高度
  • document.body.scrollHeight 內容高度 (兼容性寫法)
    let bodyHeight = document.body.scrollHeight || document.documentElement.scrollHeight;
  1. 自定義指令 v-scroll
directives: {
  /** * 滾動加載的自定義指令 */
  scroll: {
    bind(el, binding, vnode) {
      window.addEventListener('scroll', vnode.context.scrollLoad)
    },
    unbind(el, binding, vnode) {
      window.removeEventListener('scroll', vnode.context.scrollLoad)
    }
  }
},
methods: {
  scrollLoad() {
    //滾動條高度(頁面被捲去高度)
    let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
    //文檔高度
    let bodyHeight = document.body.scrollHeight || document.documentElement.scrollHeight;
    // 滾動條高度 + 瀏覽器高度 >= 文檔高度 - 閾值
    if (scrollTop + window.innerHeight >= bodyHeight - 300) {
      // 判斷請求發送標誌位,避免重複請求
      if (this.loading) return;
      // 加載的頁碼和每次滾動加載的數量,中data中聲明
      if (this.listIndex * this.PageQty >= this.total) return;
      this.listIndex++
      // 獲取商品數據的異步操做
      this.getProductList(this.listIndex)
    }
  }
}
複製代碼

這裏須要注意:java

  1. 由於發送請求和滾動事件的方法定義在了組件的 methods中,須要拿到Vue實例,但在自定義指令裏,不能經過 this 拿到Vue實例,而是經過指令鉤子函數的第三個參數 vnodecontext 屬性拿node

  2. 必需要在unbind鉤子中解綁滾動加載事件,不然在其餘頁面也會被觸發。瀏覽器

使用時,由於基於文檔高度和滾動條高度,綁在哪裏無所謂。異步

<template>
  <div id="index" v-scroll>
    <ul>
      <li v-for="(item, index) in productList" :key="index">
      </li>
    </ul>
  </div>
</template>
複製代碼
相關文章
相關標籤/搜索