这篇文章主要介绍了vue移动UI框架加载的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

前言

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

效果展示

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

DOM结构

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

<div ref="scroll">
 <div>
  <slot></slot>
 </div>
 <slot name="loading">
  <div v-show="isLoading">
   <r-loading></r-loading>
   <span>{{loadingText}}</span>
  </div>
 </slot>
 <slot name="complate">
  <div v-show="isComplate">{{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

交互逻辑分析:

    页面初始化的时候,获取整个组件节点以及正文容器节点 对整个容器节点进行绑定scroll事件 容器进行的过程中判断是否距离顶部小于指定数值,如果小于则触发自定义事件loadmore 业务代码中监听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>
  <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>
  <r-scroll ref="scroll" @loadmore="queryDate">
   <div 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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持爱安网。

最新资讯
张忠谋:老将二度离场

张忠谋:老将二度离场

56岁创业,78岁二度出山,有赞誉称他是台湾的“半导体教父
A站争夺战:为什么快手成了最后的赢家?

A站争夺战:为什么快手

对于中国互联网巨头而言,不断变大、占据战略地位,在多个
苹果CEO库克:中美贸易摩擦不会导致iPhone加税

苹果CEO库克:中美贸易

尽管外界对中美贸易摩擦的担忧日益升温,但苹果CEO库克
傅盛:与焦虑共生,更以焦虑反抗平庸

傅盛:与焦虑共生,更以焦

2008年,刚满30岁的傅盛离职,张颖看到这个消息,要来电话打
快手收购A站进军二次元,七亿老铁能容得下百万猴子吗?

快手收购A站进军二次

百万“猴子”终于有了新归宿,不是马云爸爸,不是“不站队
苹果WWDC大会发布了什么创新的功能?并没有

苹果WWDC大会发布了什

一场发布会的精彩程度,和演讲者说“isn't that cool”
最新文章
JS动画定时器知识总结

JS动画定时器知识总结

这篇文章给大家总结了关于JS动画中定时器的相关用法以
vue利用axios来完成数据的交互

vue利用axios来完成数

这篇文章主要介绍了vue利用axios来完成数据的交互,本
剖析Angular Component的源码示例

剖析Angular Componen

本篇文章主要介绍了剖析Angular Component的源码示例,
JS中原始值和引用值的储存方式示例详解

JS中原始值和引用值的

原始值指的是代表原始数据类型的值,也叫基本数据类型,引
JavaScript 五大常见函数

JavaScript 五大常见

在javascript前端开发中js函数问题经常会被讨论,这个问
Angular学习笔记之集成三方UI框架、控件的示例

Angular学习笔记之集

这篇文章主要介绍了Angular学习笔记之集成三方UI框架