vue移动UI框架滑动加载数据的方法


Posted in Javascript onMarch 12, 2018

前言

在我们移动端还有一个很常用的组件,那就是滑动加载更多组件。平常我们看到的很多插件实现相当复杂就觉得这个组件很难,其实不是的!!这个组件其实可以很简单的就实现出来,而且体验也能非常的棒(当然我们没有实现下拉刷新功能)!!下面我们就一起来实现这个组件。

效果展示

先上一个gif图片展示我们做成后的效果,如下:

vue移动UI框架滑动加载数据的方法

DOM结构

页面应该包含三个部分:1. 正文区域 2.加载小菊花以及记载文字 3.所有数据加载完成后的文字:

<div ref="scroll" class="r-scroll">
 <div class="r-scroll-wrap">
  <slot></slot>
 </div>
 <slot name="loading">
  <div v-show="isLoading" class="r-scroll-loading">
   <r-loading></r-loading>
   <span class="r-scroll-loading-text">{{loadingText}}</span>
  </div>
 </slot>
 <slot name="complate">
  <div v-show="isComplate" class="r-scroll-loading">{{complateText}}</div>
 </slot>
</div>

css样式

整个组件的容器r-scroll应该是固定宽度,超出部分可以滚动的;正文区域应该是随着内容,高度自动增长的;加载小菊花在滚动距离底部默认数值的时候显示;所有数据加载完成后显示数据加载完成文字:

<style lang="scss">
@mixin one-screen {
 position: absolute;
 left:0;
 top:0;
 width:100%;
 height:100%;
 overflow: hidden;
}
@mixin overflow-scroll {
 overflow: scroll;
 -webkit-overflow-scrolling: touch;
}

.r-scroll{
 @include one-screen;
 @include overflow-scroll;
 &-loading{
  text-align: center;
  padding-top: 3vw;
  padding-bottom: 3vw;
  font-size: 14px;
  color: #656565;
  line-height: 20px;
  &-text{
   display: inline-block;
   vertical-align: middle;
  }
 }
}
</style>

javascript

交互逻辑分析:

  1. 页面初始化的时候,获取整个组件节点以及正文容器节点
  2. 对整个容器节点进行绑定scroll事件
  3. 容器进行滚动的过程中判断是否距离顶部小于指定数值,如果小于则触发自定义事件loadmore
  4. 业务代码中监听loadmore事件,如果触发则加载数据

因为代码不复杂,故不详细解析,大家看下代码注释,如有不清楚的请在评论中发表评论:

<script>
import rLoading from '../loading'
export default{
 components: {rLoading},
 props: {
  // 距离底部数值,小于或等于该数值触发自定义事件loadmore
  bottomDistance: {
   type: [Number, String],
   default: 70
  },
  // 加载中的文字
  loadingText: {
   type: String,
   default: '加载中...'
  },
  // 数据加载完成的文字
  complateText: {
   type: String,
   default: '-- 我是个有底线的列表 --'
  }
 },
 data () {
  return {
   // 用来判定数据是否加载完成
   isComplate: false,
   // 用来判定是否正在加载数据
   isLoading: false,
   // 组件容器
   scroll: null,
   // 正文容器
   scrollWrap: null
  }
 },
 watch: {
  // 监听isLoading,如果isLoading的值为true则代表触发了loadmore事件
  isLoading (val) {
   if (val) {
    this.$emit('loadmore')
   }
  }
 },
 methods: {
  // 初始化组件,获取组件容器、正文容器节点,并给组件容器节点绑定滚动事件
  init () {
   this.scroll = this.$refs.scroll
   this.scrollWrap = this.scroll.childNodes[0]
   this.scroll.addEventListener('scroll', this.scrollEvent)
   this.$emit('init', this.scroll)
  },
  scrollEvent (e) {
   // 如果数据全部加载完成了,则再也不触发loadmore事件
   if (this.isComplate) return
   let scrollTop = this.scroll.scrollTop
   let scrollH = this.scroll.offsetHeight
   let scrollWrapH = this.scrollWrap.offsetHeight
   // 组件容器滚的距离 + 组件容器本身距离大于或者等于正文容器高度 - 指定数值 则触发loadmore事件
   if (scrollTop + scrollH >= scrollWrapH - this.bottomDistance) {
    this.isLoading = true
   }
  },
  // 当前数据加载完成后调用该函数
  loaded () {
   this.isLoading = false
  },
  // 所有数据加载完成后调用该函数
  compleate () {
   this.isLoading = false
   this.isComplate = true
   this.scroll.removeEventListener('scroll', this.scrollEvent)
  }
 },
 mounted () {
  this.$nextTick(this.init)
 }
}
</script>

另外该组件中引用到了loading小菊花组件,附录一个小菊花组件代码,因代码简单故不详细解析:

菊花使用的是一张gif图片,请照一张你喜欢的菊花gif放在该菊花组件的路径下

<template>
 <div class="r-loading-container">
  <img src="./loading.gif">
 </div>
</template>
<script>
export default {}
</script>
<style lang="scss">
.r-loading-container{
 display: inline-block;
 vertical-align: middle;
 img{
  width: 20px;
  height: 20px;
  display: block;
 }
}
</style>

写在最后

最后这里附录一个使用例子吧:

<template>
 <div class="index">
  <r-scroll ref="scroll" @loadmore="queryDate">
   <div class="item" v-for="(item, index) in list">{{item}}</div>
  </r-scroll>
 </div>
</template>

<script>
import rScroll from '../../components/scroll'
function timeout (ms) {
 return new Promise((resolve, reject) => {
  setTimeout(resolve, ms, 'done')
 })
}

export default{
 components: {rScroll},
 data () {
  return {
   i: 0,
   list: []
  }
 },
 methods: {
  async queryDate () {
   await timeout(1000)
   let i = this.i
   let data = []
   for (let j = 0; j < 40; j++) {
    data.push(i + j)
    this.i = this.i + 1
   }
   this.list = this.list.concat(data)
   // 调用组件中的loaded函数,如果数据加载完成后记得调用组件的compleate函数
   this.$refs.scroll.loaded()
  }
 },
 mounted () {
  this.queryDate()
 }
}
</script>

<style lang="scss">
.item{
 background-color: #f2f2f2;
 border-bottom: 1px solid #fff;
 height: 40px;
 line-height: 40px;
 text-align: center;
}
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS模拟的QQ面板上的多级可展开的菜单
Oct 10 Javascript
关于js中for in的缺陷浅析
Dec 02 Javascript
原生JS实现响应式瀑布流布局
Apr 02 Javascript
JS根据生日算年龄的方法
May 05 Javascript
解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法
Dec 03 Javascript
jQuery Ajax Post 回调函数不执行问题的解决方法
Aug 15 Javascript
AngularJs bootstrap搭载前台框架——js控制部分
Sep 01 Javascript
Vue2 使用 Echarts 创建图表实例代码
May 18 Javascript
Node.js 进程平滑离场剖析小结
Jan 24 Javascript
基于Vue实现微前端的示例代码
Apr 24 Javascript
Vue(定时器)解决mounted不能获取到data中的数据问题
Jul 30 Javascript
React 条件渲染最佳实践小结(7种)
Sep 27 Javascript
详解vuex的简单使用
Mar 12 #Javascript
js提取中文拼音首字母的封装工具类
Mar 12 #Javascript
基于express中路由规则及获取请求参数的方法
Mar 12 #Javascript
Node.JS段点续传:Nginx配置文件分段下载功能的实现方法
Mar 12 #Javascript
javascript变量提升和闭包理解
Mar 12 #Javascript
浅谈angular4.0中路由传递参数、获取参数最nice的写法
Mar 12 #Javascript
Vue 仿QQ左滑删除组件功能
Mar 12 #Javascript
You might like
用Php实现链结人气统计
2006/10/09 PHP
PHP 数字左侧自动补0
2008/03/31 PHP
php单例模式实现方法分析
2015/03/14 PHP
简单的js分页脚本
2009/05/21 Javascript
js实现翻页后保持checkbox选中状态的实现方法
2012/11/03 Javascript
关于JavaScript中string 的replace
2013/04/12 Javascript
非常漂亮的JS+CSS图片幻灯切换特效
2013/11/20 Javascript
扒一扒JavaScript 预解释
2015/01/28 Javascript
jQuery如何封装输入框插件
2016/08/19 Javascript
Vue计算属性的学习笔记
2017/03/22 Javascript
Node.js自定义实现文件路由功能
2017/09/22 Javascript
在vue中使用vue-echarts-v3的实例代码
2018/09/13 Javascript
微信小程序实现渐入渐出动画效果
2019/06/13 Javascript
微信小程序按钮点击动画效果的实现
2019/09/04 Javascript
小程序登录之支付宝授权的实现示例
2019/12/13 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
2020/04/07 Javascript
利用JavaScript为句子加标题的3种方法示例
2021/01/05 Javascript
python的类变量和成员变量用法实例教程
2014/08/25 Python
Python字符串和文件操作常用函数分析
2015/04/08 Python
浅析Python中将单词首字母大写的capitalize()方法
2015/05/18 Python
Django实现支付宝付款和微信支付的示例代码
2018/07/25 Python
使用OpenCV实现仿射变换—旋转功能
2019/08/29 Python
如何配置关联Python 解释器 Anaconda的教程(图解)
2020/04/30 Python
Python正则表达式如何匹配中文
2020/05/27 Python
python 字符串的驻留机制及优缺点
2020/06/19 Python
高校学生干部的自我评价分享
2013/11/04 职场文书
办公室内勤工作职责
2013/12/11 职场文书
宝宝周岁宴答谢词
2014/01/26 职场文书
行政人事岗位职责
2014/03/17 职场文书
网吧最新创业计划书范文
2014/03/27 职场文书
幼儿园清明节活动总结
2014/07/04 职场文书
医学生自荐信范文(2016精选篇)
2016/01/28 职场文书
2016年“我们的节日·端午节”活动总结
2016/04/01 职场文书
600字作文之感受大自然
2019/11/27 职场文书
python基础详解之if循环语句
2021/04/24 Python
深入理解 Golang 的字符串
2022/05/04 Golang