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


Posted in Javascript onJuly 19, 2017

上一篇讲到在项目中使用上拉加载更多组件,但是由于实际项目开发中由于需求变更或者说在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 组件滑动加载更多源码解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Jquery拖拽并简单保存的实现代码
Nov 28 Javascript
循环 vs 递归浅谈
Feb 28 Javascript
JS按字节截取字符长度实例
Nov 20 Javascript
移动节点的jquery代码
Jan 13 Javascript
JavaScript实现Java中StringBuffer的方法
Feb 09 Javascript
JS实现三级折叠菜单特效,其它级可自动收缩
Aug 06 Javascript
微信小程序 WXDropDownMenu组件详解及实例代码
Oct 24 Javascript
ajax图片上传,图片异步上传,更新实例
Dec 30 Javascript
Vue自定义图片懒加载指令v-lazyload详解
Dec 31 Javascript
vue中设置、获取、删除cookie的方法
Sep 21 Javascript
TypeScript基础入门教程之三重斜线指令详解
Oct 22 Javascript
基于Vue+ElementUI的省市区地址选择通用组件
Nov 20 Javascript
JS实现的走迷宫小游戏完整实例
Jul 19 #Javascript
JS设置随机出现2个数字的实例代码
Jul 19 #Javascript
利用jQuery异步上传文件的插件用法详解
Jul 19 #jQuery
JavaScript 值类型和引用类型的初次研究(推荐)
Jul 19 #Javascript
基于bootstrap实现多个下拉框同时搜索功能
Jul 19 #Javascript
深入理解vue2.0路由如何配置问题
Jul 18 #Javascript
JavaScript实现二维坐标点排序效果
Jul 18 #Javascript
You might like
PHP4 与 MySQL 数据库操作函数详解
2006/10/09 PHP
CentOS 6.3下安装PHP xcache扩展模块笔记
2014/09/10 PHP
php设计模式之单例模式代码
2016/06/11 PHP
thinkPHP引入类的方法详解
2016/12/08 PHP
php中青蛙跳台阶的问题解决方法
2018/10/14 PHP
JavaScript 浏览器验证代码(来自discuz)
2010/07/17 Javascript
在JavaScript并非所有的一切都是对象
2013/04/11 Javascript
javascript按位非运算符的使用方法
2013/11/14 Javascript
详解javascript中的事件处理
2015/11/06 Javascript
JavaScript中的继承之类继承
2016/05/01 Javascript
移动端横屏的JS代码(beta)
2016/05/16 Javascript
javascript中Number的方法小结
2016/11/21 Javascript
jQuery Chosen通用初始化
2017/03/07 Javascript
JS/jquery实现一个网页内同时调用多个倒计时的方法
2017/04/27 jQuery
实现图片首尾平滑轮播(JS原生方法—节流)
2017/10/17 Javascript
webpack 单独打包指定JS文件的方法
2018/02/22 Javascript
微信分享invalid signature签名错误踩过的坑
2020/04/11 Javascript
使用BeautifulSoup爬虫程序获取百度搜索结果的标题和url示例
2014/01/19 Python
批量获取及验证HTTP代理的Python脚本
2017/04/23 Python
Python函数式编程
2017/07/20 Python
Python科学计算包numpy用法实例详解
2018/02/08 Python
python 删除非空文件夹的实例
2018/04/26 Python
Python使用googletrans报错的解决方法
2018/09/25 Python
wxPython实现分隔窗口
2019/11/19 Python
Python绘制二维曲线的日常应用详解
2019/12/04 Python
对python中return与yield的区别详解
2020/03/12 Python
python 指定源路径来解决import问题的操作
2021/03/04 Python
使用css3制作登录表单的步骤
2014/04/07 HTML / CSS
Spartoo英国:欧洲最大的网上鞋店
2016/09/13 全球购物
营销与策划应届生求职信
2013/11/04 职场文书
个人简历自我评价
2014/02/02 职场文书
大学共青团员个人自我评价
2014/04/16 职场文书
中华美德颂演讲稿
2014/05/20 职场文书
销售员岗位职责
2015/02/10 职场文书
综合办公室主任岗位职责
2015/04/01 职场文书
使用Ajax实现进度条的绘制
2022/04/07 Javascript