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 相关文章推荐
jQuery操作 input type=checkbox的实现代码
Jun 14 Javascript
Javascript模块化编程(一)模块的写法最佳实践
Jan 17 Javascript
网页中表单按回车就自动提交的问题的解决方案
Nov 03 Javascript
jQuery对象的length属性用法实例
Dec 27 Javascript
jQuery实现简单滚动动画效果
Apr 07 Javascript
Javascript for in的缺陷总结
Feb 03 Javascript
JavaScript实现的选择排序算法实例分析
Apr 14 Javascript
webpack 从指定入口文件中提取公共文件的方法
Nov 13 Javascript
iview实现select tree树形下拉框的示例代码
Dec 21 Javascript
原生js实现公告滚动效果
Jan 10 Javascript
Vue 解决父组件跳转子路由后当前导航active样式消失问题
Jul 21 Javascript
vue修改Element的el-table样式的4种方法
Sep 17 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
phpmyadmin里面导入sql语句格式的大量数据的方法
2010/06/05 PHP
JS 自动完成 AutoComplete(Ajax 查询)
2009/07/07 Javascript
Javascript 面向对象 重载
2010/05/13 Javascript
如何在node的express中使用socket.io
2014/12/15 Javascript
angularjs 处理多个异步请求方法汇总
2015/01/06 Javascript
javascript判断数组内是否重复的方法
2015/04/21 Javascript
jquery插件splitScren实现页面分屏切换模板特效
2015/06/16 Javascript
js+css实现的圆角边框TAB选项卡滑动门代码分享(2款)
2015/08/26 Javascript
深入学习jQuery Validate表单验证(二)
2016/01/18 Javascript
清除js缓存的多种方法总结
2016/12/09 Javascript
Linux CentOS系统下安装node.js与express的方法
2017/04/01 Javascript
JavaScript实现自动跳转文本功能
2017/05/25 Javascript
Vue 理解之白话 getter/setter详解
2019/04/16 Javascript
如何使用Jquery动态生成二级选项列表
2020/02/06 jQuery
原生js实现ajax请求和JSONP跨域请求操作示例
2020/03/14 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
2020/05/19 jQuery
Vuex的热更替如何实现
2020/06/05 Javascript
ES6中的Javascript解构的实现
2020/10/30 Javascript
详解微信小程序「渲染层网络层错误」的解决方法
2021/01/06 Javascript
在Python中使用itertools模块中的组合函数的教程
2015/04/13 Python
python网络编程之文件下载实例分析
2015/05/20 Python
Python实现读取并保存文件的类
2017/05/11 Python
Django 登陆验证码和中间件的实现
2018/08/17 Python
Linux上使用Python统计每天的键盘输入次数
2019/04/17 Python
Python函数的返回值、匿名函数lambda、filter函数、map函数、reduce函数用法实例分析
2019/12/26 Python
Python3 读取Word文件方式
2020/02/13 Python
法国一家芭蕾舞鞋公司:Repetto
2018/11/12 全球购物
贷款委托书范本
2014/04/08 职场文书
企业文化演讲稿
2014/05/20 职场文书
亚运会口号
2014/06/20 职场文书
董事长助理工作职责范本
2014/07/01 职场文书
绘画专业自荐信
2014/07/04 职场文书
小学生运动会广播
2015/08/19 职场文书
银行客户经理培训心得体会
2016/01/09 职场文书
2019年七夕情人节浪漫祝福语大全!
2019/08/08 职场文书
nginx共享内存的机制详解
2022/03/21 Servers