最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue loadmore 組件滑動(dòng)加載更多源碼解析

 更新時(shí)間:2017年07月19日 09:58:41   作者:BenjaminShih  
這篇文章主要介紹了vue loadmore 組件滑動(dòng)加載更多源碼解析,需要的朋友可以參考下

上一篇講到在項(xiàng)目中使用上拉加載更多組件,但是由于實(shí)際項(xiàng)目開(kāi)發(fā)中由于需求變更或者說(shuō)在webview中上拉加載有些機(jī)型在上拉時(shí)候會(huì)把webview也一起上拉導(dǎo)致上拉加載不靈敏等問(wèn)題,我們有時(shí)候也會(huì)換成滑動(dòng)到底部自動(dòng)加載的功能。

既然都是加載更多,很多代碼思想勢(shì)必相似,主要區(qū)別在于上拉和滑動(dòng)到底部這個(gè)操作上,所以,我們需要注意:

上拉加載是point指針touch觸摸事件,現(xiàn)在因?yàn)槭腔瑒?dòng)加載,需要添加scroll事件去監(jiān)聽(tīng)然后執(zhí)行相應(yīng)回調(diào)

上拉加載主要計(jì)算觸摸滾動(dòng)距離,滑動(dòng)加載主要計(jì)算container底部和視窗上邊緣的距離

事件綁定改成: 

 mounted() {
  ···
  this.dom.addEventListener('scroll', this.scroll, false)
  ···
 },
 beforeDestroy() {
  ···
  this.dom.removeEventListener('scroll', this.scroll, false)
  ···
 },

事件回調(diào)改為:

 /**
  * 滾動(dòng)鉤子
  */
  scroll() {
  const viewHeight = global.innerHeight
  let parentNode
  if (this.container !== global) {
   parentNode = this.$el
  } else {
   parentNode = this.$el.parentNode
  }
  if (parentNode) {
   // 獲取Vue實(shí)例使用的根 DOM 元素相對(duì)于視口的位置
   const rect = parentNode.getBoundingClientRect()
   // this.distance 離底部多少距離開(kāi)始加載
   // 如果此元素底邊距離視口頂部的距離小于視口高度加上distance之和,就加載下一頁(yè)
   if ((rect.bottom <= viewHeight + this.distance) && this.loadable && !this.loading) {
   this.load()
   }
  }
  },

源碼如下:

<template>
 <div class="loadmore" ref="loadmore">
 <div class="loadmore__body">
  <slot></slot>
 </div>
 <div class="loadmore__footer">
  <span v-if="loading">
  <i class="tc-loading"></i>
  <span>正在加載</span>
  </span>
  <span v-else-if="loadable">加載更多</span>
  <span v-else>沒(méi)有更多了</span>
 </div>
 </div>
</template>
<script type="text/babel">
 import axios from 'axios'
 const CancelToken = axios.CancelToken
 export default {
 data() {
  return {
  /**
   * 總頁(yè)數(shù)(由服務(wù)端返回)
   * @type {number}
   */
  count: 0,
  /**
   * 是否正在拖拽中
   * @type {boolean}
   */
  dragging: false,
  /**
   * 已加載次數(shù)
   * @type {number}
   */
  times: 0,
  /**
   * 已開(kāi)始記載
   * @type {boolean}
   */
  started: false,
  /**
   * 正在加載中
   * @type {boolean}
   */
  loading: false,
  dom: null,
  }
 },
 props: {
  /**
  * 初始化后自動(dòng)開(kāi)始加載數(shù)據(jù)
  */
  autoload: {
  type: Boolean,
  default: true,
  },
  /**
  * 離組件最近的可滾動(dòng)父級(jí)元素(用于監(jiān)聽(tīng)事件及獲取滾動(dòng)條位置)
  */
  container: {
  // Selector or Element
  default: () => (global),
  },
  /**
  * Axios請(qǐng)求參數(shù)配置對(duì)象
  * {@link https://github.com/mzabriskie/axios#request-config}
  */
  options: {
  type: Object,
  default: null,
  },
  /**
  * 起始頁(yè)碼
  */
  page: {
  type: Number,
  default: 1,
  },
  /**
  * 每頁(yè)加載數(shù)據(jù)條數(shù)
  */
  rows: {
  type: Number,
  default: 10,
  },
  /**
  * 數(shù)據(jù)加載請(qǐng)求地址
  */
  url: {
  type: String,
  default: '',
  },
  /**
  * 距離底部多遠(yuǎn)加載
  */
  distance: {
  type: Number,
  default: 200,
  },
 },
 computed: {
  /**
  * 是否可以加載
  * @returns {boolean} 是與否
  */
  loadable() {
  return !this.started || (this.page + this.times) <= this.count
  },
 },
 mounted() {
  if (this.container !== global) {
  this.dom = document.querySelector(this.container)
  } else {
  this.dom = this.container
  }
  if (!this.dom) {
  return
  }
  this.dom.addEventListener('scroll', this.scroll, false)
  if (this.autoload && !this.loading) {
  this.load()
  }
 },
 // eslint-disable-next-line
 beforeDestroy() {
  if (this.dom) {
  this.dom.removeEventListener('scroll', this.scroll, false)
  }
 },
 methods: {
  /**
  * 滾動(dòng)鉤子
  */
  scroll() {
  const viewHeight = global.innerHeight
  let parentNode
  if (this.container !== global) {
   parentNode = this.$el
  } else {
   parentNode = this.$el.parentNode
  }
  if (parentNode) {
   const rect = parentNode.getBoundingClientRect()
   if ((rect.bottom <= viewHeight + this.distance) && this.loadable && !this.loading) {
   this.load()
   }
  }
  },
  /**
  * 加載一組數(shù)據(jù)的方法
  */
  load() {
  if (this.loading) {
   return
  }
  this.started = true
  this.loading = true
  const params = {
   currentPage: this.page + this.times,
   pageSize: this.rows,
  }
  const options = Object.assign({}, this.options, {
   url: this.url,
   cancelToken: new CancelToken((cancel) => {
   this.cancel = cancel
   }),
  })
  if (String(options.method).toUpperCase() === 'POST') {
   options.data = Object.assign({}, options.data, params)
  } else {
   options.params = Object.assign({}, options.params, params)
  }
  this.$axios.request(options).then((res) => {
   const data = res.result
   this.times += 1
   this.loading = false
   this.count = data.pageCount
   this.$emit('success', data.list)
   this.$emit('complete')
  }).catch((e) => {
   this.loading = false
   this.$emit('error', e)
   this.$emit('complete')
  })
  },
  /**
  * 重置加載相關(guān)變量
  */
  reset() {
  this.count = 0
  this.times = 0
  this.started = false
  this.loading = false
  },
  /**
  *重新開(kāi)始加載
  */
  restart() {
  this.reset()
  this.load()
  },
 },
 }
</script>

以上所述是小編給大家介紹的vue loadmore 組件滑動(dòng)加載更多源碼解析,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 在Vue中實(shí)現(xiàn)圖表數(shù)據(jù)的動(dòng)態(tài)展示的示例代碼

    在Vue中實(shí)現(xiàn)圖表數(shù)據(jù)的動(dòng)態(tài)展示的示例代碼

    隨著數(shù)據(jù)可視化技術(shù)的發(fā)展,圖表在前端開(kāi)發(fā)中扮演著越來(lái)越重要的角色,Vue.js 作為一個(gè)流行的前端框架,以其靈活性和易用性,成為了實(shí)現(xiàn)圖表動(dòng)態(tài)展示的理想選擇,在這篇博客中,我們將學(xué)習(xí)如何在 Vue 3 中實(shí)現(xiàn)動(dòng)態(tài)展示圖表數(shù)據(jù),需要的朋友可以參考下
    2024-11-11
  • Vue使用Print.js打印div方式(選中區(qū)域的html)

    Vue使用Print.js打印div方式(選中區(qū)域的html)

    這篇文章主要介紹了Vue使用Print.js打印div方式(選中區(qū)域的html),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • element-plus報(bào)錯(cuò)ResizeObserver?loop?limit?exceeded解決辦法

    element-plus報(bào)錯(cuò)ResizeObserver?loop?limit?exceeded解決辦法

    這篇文章主要給大家介紹了關(guān)于element-plus報(bào)錯(cuò)ResizeObserver?loop?limit?exceeded的解決辦法,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Vue-element-admin平臺(tái)側(cè)邊欄收縮控制問(wèn)題

    Vue-element-admin平臺(tái)側(cè)邊欄收縮控制問(wèn)題

    這篇文章主要介紹了Vue-element-admin平臺(tái)側(cè)邊欄收縮控制問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue axios整合使用全攻略

    vue axios整合使用全攻略

    這篇文章主要介紹了vue axios整合使用全攻略,需要的朋友可以參考下
    2018-05-05
  • element-ui中導(dǎo)航組件menu的一個(gè)屬性:default-active說(shuō)明

    element-ui中導(dǎo)航組件menu的一個(gè)屬性:default-active說(shuō)明

    這篇文章主要介紹了element-ui中導(dǎo)航組件menu的一個(gè)屬性:default-active說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Vue如何實(shí)現(xiàn)組件間通信

    Vue如何實(shí)現(xiàn)組件間通信

    組件間通信簡(jiǎn)單來(lái)說(shuō)就是組件間進(jìn)行數(shù)據(jù)傳遞。就像我們?nèi)粘5拇螂娫?,就是通訊的一種方式,你把話說(shuō)給我聽(tīng),我把話說(shuō)給你聽(tīng),說(shuō)的話就是數(shù)據(jù)。電話就是通訊方式的一種。無(wú)論是 Vue 還是 React ,都得進(jìn)行組件間通信。
    2021-05-05
  • Electron自動(dòng)更新失效報(bào)錯(cuò)Error:?Object?has?been?destroyed的問(wèn)題解決

    Electron自動(dòng)更新失效報(bào)錯(cuò)Error:?Object?has?been?destroyed的問(wèn)題解決

    本文主要講解如何解決?Error:?Object?has?been?destroyed?這個(gè)?Electron?中最常見(jiàn)的問(wèn)題,以及?Electron?自動(dòng)更新的流程,文中通過(guò)代碼示例給大家講解的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Vue鼠標(biāo)右鍵畫(huà)矩形和Ctrl按鍵多選組件方式

    Vue鼠標(biāo)右鍵畫(huà)矩形和Ctrl按鍵多選組件方式

    文章介紹了一個(gè)Vue組件,該組件允許用戶通過(guò)鼠標(biāo)右鍵在畫(huà)布上繪制矩形,并且支持通過(guò)Ctrl鍵進(jìn)行多選,文章附帶了組件代碼和一個(gè)示例,建議讀者將代碼復(fù)制到自己的開(kāi)發(fā)環(huán)境中進(jìn)行調(diào)試
    2024-12-12
  • Vue生命周期中的八個(gè)鉤子函數(shù)相機(jī)

    Vue生命周期中的八個(gè)鉤子函數(shù)相機(jī)

    這篇文章主要為大家介紹了Vue生命周期中的八個(gè)鉤子函數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12

最新評(píng)論

珠海市| 西丰县| 荔波县| 宁晋县| 武隆县| 白沙| 察隅县| 海阳市| 藁城市| 舟曲县| 棋牌| 东海县| 新蔡县| 峨眉山市| 富阳市| 新化县| 黄陵县| 宜兴市| 台州市| 荆州市| 来凤县| 甘泉县| 昭平县| 电白县| 淅川县| 嵊泗县| 芜湖县| 梁山县| 开原市| 蓝田县| 古蔺县| 宁化县| 黔西| 博野县| 应用必备| 巴青县| 句容市| 云龙县| 遂昌县| 张掖市| 海门市|