国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue loadmore組件上拉加載更多功能示例代碼

2019-11-19 16:02:40
字體:
供稿:網(wǎng)友

最近在做移動端h5頁面,所以分頁什么的就不能按照傳統(tǒng)pc端的分頁器的思維去做了,這么小的屏幕去點擊也不太方便一般來講移動端都是上拉加載更多,符合正常使用習(xí)慣。

首先簡單寫一下模板部分的html代碼,,很簡單清晰的邏輯:

<template> <div class="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>沒有更多了</span>  </div> </div></template>

然后就是業(yè)務(wù)部分了

在動手寫組件之前,先理清需求:

加載頁面 -> 滑到底部 -> 上拉一定距離 -> 加載第二頁 -> 繼續(xù)前面步驟 -> 沒有更多

這是一個用戶交互邏輯,而我們需要將其映射為代碼邏輯:

首屏自動加載第一頁 -> 滑動到底部&&按下時候滑動距離Y軸有一定偏移量 -> 請求后端加載第二頁 -> 根據(jù)返回字段判斷是否還有下一頁

有了代碼邏輯,主干就出來了,加載和判斷由事件來控制,而又作為一個vue組件,我們需要配合vue生命周期來掛載事件和銷毀事件

export default {  mounted() {    // 確定容器    // 容器綁定事件  },  beforeDestory() {    // 解綁事件  },}

如果沒有解綁的話,每次你加載組件,就會綁定一次事件…

然后我們需要一些核心事件回調(diào)方法來在合適的時間加載數(shù)據(jù)渲染頁面, 回想一下,第一我們需要http獲取數(shù)據(jù)的load函數(shù),然后我們需要三個綁定事件的回調(diào)函數(shù)pointDown(), pointMove(), pointUp(),分別對應(yīng)用戶按下、移動、彈起手指操作:

export default {  ???  methods:{   /**    * 加載一組數(shù)據(jù)的方法    */   load() {     // 設(shè)置options    this.$axios.request(options).then((res) => {      // 獲取數(shù)據(jù)后的處理    }).catch((e) => {     // 異常處理    })   },    /**    * 鼠標按下事件處理函數(shù)    * @param {Object} e - 事件對象    */   pointerdown(e) {    // 獲取按下的位置    this.pageY = e.changedTouches ? e.changedTouches[0].pageY : e.pageY   },    /**    * 鼠標移動事件處理函數(shù)    * @param {Object} e - 事件對象    */   pointermove(e) {    const container = this.$container    const pageY = e.changedTouches ? e.changedTouches[0].pageY : e.pageY    const moveY = pageY - this.pageY    // 如果已經(jīng)向下滾動到頁面最底部    if (moveY < 0 && (container.scrollTop + Math.min(     global.innerHeight,     container.clientHeight,    )) >= container.scrollHeight) {     // 阻止原生的上拉拖動會露出頁面底部空白區(qū)域的行為(主要針對iOS版微信)     e.preventDefault()     // 如果上拉距離超過50像素,則加載下一頁     if (moveY < -50) {      this.pageY = pageY      this.load()     }    }   },    /**    * 鼠標松開事件處理函數(shù)    */   pointerup() {    // 這邊就是取消拖動狀態(tài),需要注意在拖動過程中不要再次觸發(fā)一些事件回調(diào),否側(cè)亂套    this.dragging = false   },  },  ???}

基本上主干已經(jīng)算完工了,一些props傳入或者一些邏輯控制細節(jié)需要再額外添加,貼出整個組件的源碼:

<template> <div class="loadmore">  <!-- <div class="loadmore__header"></div> -->  <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>沒有更多了</span>  </div> </div></template><script type="text/babel"> import axios from 'axios' const CancelToken = axios.CancelToken export default {  data() {   return {    /**     * 總頁數(shù)(由服務(wù)端返回)     * @type {number}     */    count: 0,    /**     * 是否正在拖拽中     * @type {boolean}     */    dragging: false,    /**     * 已加載次數(shù)     * @type {number}     */    times: 0,    /**     * 已開始記載     * @type {boolean}     */    started: false,    /**     * 正在加載中     * @type {boolean}     */    loading: false,   }  },  props: {   /**    * 初始化后自動開始加載數(shù)據(jù)    */   autoload: {    type: Boolean,    default: true,   },   /**    * 離組件最近的可滾動父級元素(用于監(jiān)聽事件及獲取滾動條位置)    */   container: {    // Selector or Element    default: 'body',   },   /**    * 禁用組件    */   disabled: {    type: Boolean,    default: false,   },   /**    * Axios請求參數(shù)配置對象    * {@link https://github.com/mzabriskie/axios#request-config}    */   options: {    type: Object,    default: null,   },   /**    * 起始頁碼    */   page: {    type: Number,    default: 1,   },   /**    * 每頁加載數(shù)據(jù)條數(shù)    */   rows: {    type: Number,    default: 10,   },   /**    * 數(shù)據(jù)加載請求地址    */   url: {    type: String,    default: '',   },  },  computed: {   /**    * 是否可以加載    * @returns {boolean} 是與否    */   loadable() {    return !this.disabled && (!this.started || (this.page + this.times) <= this.count)   },  },  mounted() {   let container = this.container   if (container) {    if (typeof container === 'string') {     container = document.querySelector(container)    } else if (!container.querySelector) {     container = document.body    }   }   if (!container) {    container = document.body   }   this.$container = container   this.onPointerDown = this.pointerdown.bind(this)   this.onPointerMove = this.pointermove.bind(this)   this.onPointerUp = this.pointerup.bind(this)   if (global.PointerEvent) {    container.addEventListener('pointerdown', this.onPointerDown, false)    container.addEventListener('pointermove', this.onPointerMove, false)    container.addEventListener('pointerup', this.onPointerUp, false)    container.addEventListener('pointercancel', this.onPointerUp, false)   } else {    container.addEventListener('touchstart', this.onPointerDown, false)    container.addEventListener('touchmove', this.onPointerMove, false)    container.addEventListener('touchend', this.onPointerUp, false)    container.addEventListener('touchcancel', this.onPointerUp, false)    container.addEventListener('mousedown', this.onPointerDown, false)    container.addEventListener('mousemove', this.onPointerMove, false)    container.addEventListener('mouseup', this.onPointerUp, false)   }   if (this.autoload) {    this.load()   }  },  // eslint-disable-next-line  beforeDestroy() {   const container = this.$container   if (global.PointerEvent) {    container.removeEventListener('pointerdown', this.onPointerDown, false)    container.removeEventListener('pointermove', this.onPointerMove, false)    container.removeEventListener('pointerup', this.onPointerUp, false)    container.removeEventListener('pointercancel', this.onPointerUp, false)   } else {    container.removeEventListener('touchstart', this.onPointerDown, false)    container.removeEventListener('touchmove', this.onPointerMove, false)    container.removeEventListener('touchend', this.onPointerUp, false)    container.removeEventListener('touchcancel', this.onPointerUp, false)    container.removeEventListener('mousedown', this.onPointerDown, false)    container.removeEventListener('mousemove', this.onPointerMove, false)    container.removeEventListener('mouseup', this.onPointerUp, false)   }   if (this.loading && this.cancel) {    this.cancel()   }  },  methods: {   /**    * 加載一組數(shù)據(jù)的方法    */   load() {    if (this.disabled || 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   },   /**    *重新開始加載    */   restart() {    this.reset()    this.load()   },   /**    * 鼠標按下事件處理函數(shù)    * @param {Object} e - 事件對象    */   pointerdown(e) {    if (this.disabled || !this.loadable || this.loading) {     return    }    this.dragging = true    this.pageY = e.changedTouches ? e.changedTouches[0].pageY : e.pageY   },   /**    * 鼠標移動事件處理函數(shù)    * @param {Object} e - 事件對象    */   pointermove(e) {    if (!this.dragging) {     return    }    const container = this.$container    const pageY = e.changedTouches ? e.changedTouches[0].pageY : e.pageY    const moveY = pageY - this.pageY    // 如果已經(jīng)向下滾動到頁面最底部    if (moveY < 0 && (container.scrollTop + Math.min(     global.innerHeight,     container.clientHeight,    )) >= container.scrollHeight) {     // 阻止原生的上拉拖動會露出頁面底部空白區(qū)域的行為(主要針對iOS版微信)     e.preventDefault()     // 如果上拉距離超過50像素,則加載下一頁     if (moveY < -50) {      this.pageY = pageY      this.load()     }    }   },   /**    * 鼠標松開事件處理函數(shù)    */   pointerup() {    this.dragging = false   },  }, }</script>

以上所述是小編給大家介紹的vue loadmore組件上拉加載更多功能示例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對武林網(wǎng)網(wǎng)站的支持!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 淮北市| 濉溪县| 屯门区| 慈利县| 龙江县| 任丘市| 江永县| 阿拉善右旗| 老河口市| 理塘县| 韩城市| 彭泽县| 开封县| 鄯善县| 普格县| 喜德县| 达拉特旗| 无锡市| 恭城| 璧山县| 莲花县| 凤山市| 高要市| 泾源县| 宁晋县| 揭西县| 图片| 奉新县| 丽水市| 泸溪县| 苍梧县| 庆云县| 孝感市| 成武县| 镇赉县| 开化县| 怀宁县| 南江县| 永德县| 台州市| 玉林市|