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 相关文章推荐
javascript TextArea动态显示剩余字符
Oct 22 Javascript
Date对象格式化函数代码
Jul 17 Javascript
js split 的用法和定义 js split分割字符串成数组的实例代码
May 13 Javascript
页面加载完成后再执行JS的jquery写法以及区别说明
Feb 22 Javascript
JavaScript的null和undefined区别示例介绍
Sep 15 Javascript
jQuery Validation Plugin验证插件手动验证
Jan 26 Javascript
微信小程序开发的四十个技术窍门总结(推荐)
Jan 23 Javascript
基于vue实现swipe分页组件实例
May 25 Javascript
js实现文字列表无缝滚动效果
Jun 23 Javascript
JavaScript比较同一天的时间大小实例代码
Feb 09 Javascript
使用FormData实现上传多个文件
Dec 04 Javascript
JS判断数组是否包含某元素实现方法汇总
Jun 24 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&amp;java(三)
2006/10/09 PHP
PHP获取栏目的所有子级和孙级栏目的ID号示例
2014/04/01 PHP
WordPress中用于更新伪静态规则的PHP代码实例讲解
2015/12/18 PHP
php中关于长度计算容易混淆的问题分析
2016/05/27 PHP
用javascript实现分割提取页面所需内容
2007/05/09 Javascript
date.parse在IE和FF中的区别
2010/07/29 Javascript
JS命名空间的另一种实现
2013/08/09 Javascript
JavaScript调用ajax获取文本文件内容实现代码
2014/03/28 Javascript
jquery库文件略庞大用纯js替换jquery的方法
2014/08/12 Javascript
jquery中radio checked问题
2015/03/16 Javascript
Ajax使用原生态JS验证用户名是否存在
2020/05/26 Javascript
JQuery学习总结【一】
2016/12/01 Javascript
vue实现图书管理demo详解
2017/10/17 Javascript
Vue数据双向绑定底层实现原理
2019/11/22 Javascript
JS+CSS实现3D切割轮播图
2020/03/21 Javascript
微信小程序scroll-view点击项自动居中效果的实现
2020/03/25 Javascript
微信小程序国际化探索实现(附源码地址)
2020/05/20 Javascript
JavaScript监听键盘事件代码实现
2020/06/03 Javascript
Django实现全文检索的方法(支持中文)
2018/05/14 Python
python爬取足球直播吧五大联赛积分榜
2018/06/13 Python
python实现控制电脑鼠标和键盘,登录QQ的方法示例
2019/07/06 Python
Python timer定时器两种常用方法解析
2020/01/20 Python
python super函数使用方法详解
2020/02/14 Python
selenium设置浏览器为headless无头模式(Chrome和Firefox)
2021/01/08 Python
荷兰在线啤酒店:Beerwulf
2019/08/26 全球购物
捷科时代的软件测试笔试题
2015/11/09 面试题
留学生如何写好自荐信
2013/12/27 职场文书
大学生学业生涯规划
2014/01/05 职场文书
财务总监管理职责范文
2014/03/09 职场文书
2014年党员自我评议(5篇)
2014/09/12 职场文书
防汛工作情况汇报
2014/10/28 职场文书
优秀乡村医生事迹材料(2016精选版)
2016/02/29 职场文书
2019教师的学习计划
2019/06/25 职场文书
ConstraintValidator类如何实现自定义注解校验前端传参
2021/06/18 Java/Android
Python使用openpyxl批量处理数据
2021/06/23 Python
python多次执行绘制条形图
2022/04/20 Python