Vue無限下拉列表


在Vue.js中實現一個列表無限下拉刷新功能,最好的實現方式應該是利用自定義指令,Vue除了核心功能默認內置的指令 (v-model 和 v-show),在仍然需要對普通 DOM 元素進行底層操時,推薦使用自定義指令。Vue指令為我們提供了以下幾個鈎子函數,

const MyDirective = {
  bind(el, binding, vnode, prevVnode) {},
  inserted() {},
  update() {},
  componentUpdated() {},
  unbind() {}
}

我們這樣來設計指令的使用方式
xxx
它有三個入參,即:

  1. distance:距離底部多少距離時觸發加載方法。
  2. immediate:是否初始化時先執行加載方法,以防止初始內容太少而無法觸發滾動條。
  3. callbackFn:加載內容的函數。
    都通過鈎子函數的默認參數binding來獲取,即binding.arg, binding.modifiers, binding.value

判斷一個container元素的內容是否滾動到底部,成立條件為scrollHeight - scrollTop <= clientHeight。如果想讓內容距離底部 xxx distance時加載,則 scrollHeight - scrollTop - distance <= clientHeight
【這三個屬性都是container容器元素的屬性,而不是滾動內容元素的屬性】。容器元素高度一定是固定的,而不是由內容撐開,這樣才會有滾動條出現,當然overflow肯定不能為hidden。

  1. scrollHeight
    只讀屬性,表示一個元素內容高度,包括由於溢出導致的視圖中不可見內容。當沒有滾動條的情況下scrollHeight等於clientHeight。會對結果四舍五入進行取整,如果需要小數則使用element.getBoundingClientRect().
  2. clientHeight
    只讀屬性。
    clientHeight = 內容高度 + padding。
    offsetHeight = 內容高度 + padding + border。
  3. scrollTop
    一個元素的 scrollTop 值是這個元素的內容頂部(卷起來的)到它的視口可見內容(的頂部)的距離的度量。當一個元素的內容沒有產生垂直方向的滾動條,那么它的 scrollTop 值為0。

指令的js代碼:

export default {
  inserted(el, binding) {
    const domHeight = el.clientHeight;
    let distance = Number(binding.arg)
    if (Number.isNaN(distance)) distance = 0
    const { immediate } = binding.modifiers
    const cb = binding.value

    if (el.scrollHeight === 0) {
      console.log(`scollheigt == ${el.scrollHeight}, 請檢查overflow屬性`);
    }

    const handleScroll = () => {
      if (el.scrollHeight - el.scrollTop - distance <= domHeight) {
        console.log(el.scrollTop ,'bottom!');
        cb()
      }
    }
    el['ifsScope'] = { handleScroll } 
    
    el.addEventListener('scroll', handleScroll)

    if (immediate) {
      const observer = new MutationObserver(handleScroll)
      observer.observe(el, { childList: true, subtree: true })
      handleScroll()
    }
  },
  unbind(el) {
    let { handleScroll } = el['ifsScope']
    el.removeEventListener('scroll', handleScroll)
  }
}

然后使用局部注冊的方式使用:

import infiniteScroll from './iScroll.js'
const vm = new Vue({
  el: '#app',
  directives: { infiniteScroll },
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM