首页 > 编程 > JavaScript > 正文

vue loadmore 组件滑动加载更多源码解析

2019-11-19 16:02:42
字体:
来源:转载
供稿:网友

上一篇讲到在项目中使用上拉加载更多组件,但是由于实际项目开发中由于需求变更或者说在webview中上拉加载有些机型在上拉时候会把webview也一起上拉导致上拉加载不灵敏等问题,我们有时候也会换成滑动到底部自动加载的功能。

既然都是加载更多,很多代码思想势必相似,主要区别在于上拉和滑动到底部这个操作上,所以,我们需要注意:

上拉加载是point指针touch触摸事件,现在因为是滑动加载,需要添加scroll事件去监听然后执行相应回调

上拉加载主要计算触摸滚动距离,滑动加载主要计算container底部和视窗上边缘的距离

事件绑定改成: 

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

事件回调改为:

 /**  * 滚动钩子  */  scroll() {  const viewHeight = global.innerHeight  let parentNode  if (this.container !== global) {   parentNode = this.$el  } else {   parentNode = this.$el.parentNode  }  if (parentNode) {   // 获取Vue实例使用的根 DOM 元素相对于视口的位置   const rect = parentNode.getBoundingClientRect()   // this.distance 离底部多少距离开始加载   // 如果此元素底边距离视口顶部的距离小于视口高度加上distance之和,就加载下一页   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>没有更多了</span> </div> </div></template><script type="text/babel"> import axios from 'axios' const CancelToken = axios.CancelToken export default { data() {  return {  /**   * 总页数(由服务端返回)   * @type {number}   */  count: 0,  /**   * 是否正在拖拽中   * @type {boolean}   */  dragging: false,  /**   * 已加载次数   * @type {number}   */  times: 0,  /**   * 已开始记载   * @type {boolean}   */  started: false,  /**   * 正在加载中   * @type {boolean}   */  loading: false,  dom: null,  } }, props: {  /**  * 初始化后自动开始加载数据  */  autoload: {  type: Boolean,  default: true,  },  /**  * 离组件最近的可滚动父级元素(用于监听事件及获取滚动条位置)  */  container: {  // Selector or Element  default: () => (global),  },  /**  * Axios请求参数配置对象  * {@link https://github.com/mzabriskie/axios#request-config}  */  options: {  type: Object,  default: null,  },  /**  * 起始页码  */  page: {  type: Number,  default: 1,  },  /**  * 每页加载数据条数  */  rows: {  type: Number,  default: 10,  },  /**  * 数据加载请求地址  */  url: {  type: String,  default: '',  },  /**  * 距离底部多远加载  */  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: {  /**  * 滚动钩子  */  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()   }  }  },  /**  * 加载一组数据的方法  */  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')  })  },  /**  * 重置加载相关变量  */  reset() {  this.count = 0  this.times = 0  this.started = false  this.loading = false  },  /**  *重新开始加载  */  restart() {  this.reset()  this.load()  }, }, }</script>

以上所述是小编给大家介绍的vue loadmore 组件滑动加载更多源码解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表