Vue混入mixins滚动触底的方法

 更新时间:2019年11月22日 14:47:08   作者:三只萌新  
这篇文章主要介绍了Vue混入mixins滚动触底的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在app端常常看到类似加载数据的动画,接下来我们来实现滚动触底加载动画提示,以及如何复用这些逻辑。

如何判断滚动触底

来看下几张图:

情况一:

当文档高度还为超过可视区域高度时,不存在滚动,所以也没有滚动触底

 

情况二:

当文档高度超过可视区域的高度时,还有剩余的文档没有滚动完,也就是说 可视区域高度 + 滚动高度 < 文档高度 ,此时没有达到滚动触底的条件

 

情况三:

文档高度大于可视区域,并且滚动到文档底部, 也就是说 可视区域高度 + 滚动高度 = 文档高度

 

判断是否滚动到底

经过上面三种情况的分析,我们需要拿到 可视区域的高度 , 滚动高度 , 文档高度 这三个变量来进行比较。

可视区域的高度

function getWindowHeight() {
 return document.documentElement.clientHeight;
}

滚动高度

对有doctype申明的页面使用document.documentElement.scrollTop,safari特例独行:使用 window.pageYOffset

function getScrollHeight() {
 return Math.max(document.documentElement.scrollTop,window.pageYOffset||0)
}

文档高度

function getDocumentTop() {
 return document.documentElement.offsetHeight;
}

代码实现

触底打印

codepen 触底打印demo

通过监听滚动事件来判断 可视区域滚动高度文档高度 的关系,实现最基础的触底加载

 <div id="app">
 <ul>
  <li v-for="item in list" :key="item" > {{item}}</li>
 </ul>
 </div>
 created(){
  // 初始化数据
  this.list = Array.from(Array(10),(item,index)=>index)
  // 通过监听滚动事件来判断 可视区域 , 滚动高度 ,文档高度的关系
  window.addEventListener('scroll',()=>{
  let isBottom = (getScrollHeight() + getWindowHeight()) >= getDocumentTop()
  if(isBottom){
   console.log('触底了',new Date())
   let list = this.list
   let last = list[list.length-1]
   let newList = Array.from(Array(10),(item,index)=>index+last+1)
   this.list.push(...newList)
  }
  })
 } 

优化和复用滚动事件逻辑

将滚动逻辑抽取成 mixins 放在 scroll.js 中。优化功能点如下:

  1. 增加触底距离
  2. 滚动事件监听事件节流
  3. 添加触底动画,并将 UI 样式一起封装在 scroll.js 中

 模拟请求事件

为了模拟请求数据,封装了一个 Promise 一秒后返回结果

methods:{
 // 返回一个 promise ,用于请求服务端数据
 findDataList(){
 let list = this.list
 let last = list[list.length-1]
 return new Promise((resolve)=>{
 // 模拟服务端数据
 let newList = Array.from(Array(10),(item,index)=>index+last+1)
  setTimeout(() => {
  resolve(newList)
  }, 1000);
 })
 }
}

滚动事件监听

滚动事件触发,判断当前是否触底,触底了以后去执行 loadMore 发起请求拿取服务端的数据

 created(){
 let fn = throttle(()=>{
  let isOver = (getScrollHeight() + getWindowHeight()) >= (getDocumentTop()- MIN_INSTANCE)
  // 触底时进行数据加载
  if(isOver){
  // 创建加载组件
  this.loadMore&&this.loadMore()
  }
 },DEALY_TIME)
 window.addEventListener('scroll',fn)
 },

添加触底动画

因为我们是将逻辑抽离在 mixins中,为了把触底动画也集成在里面使用 Vue.extend() 来实现编程式插入UI样式的方法。

首先定义好 loading 组件的样式

<template>
 <div id="loading-alert">
  <i class="el-icon-loading"></i>
  <span>{{ message }}</span>
 </div>
</template>

<script>
export default {
 props:{
 message:{
  type:String,
  default:'正在加载更多数据'
 }
 },
};

当触底时去插入这个 loading 组件

import load from './load.vue'
data(){
 return {
 isLoading:false,
 component:null
 }
},
created(){
 let fn = throttle(()=>{
 let isOver = (getScrollHeight() + getWindowHeight()) >= (getDocumentTop()- MIN_INSTANCE)
 // 触底时进行load组件显示
 if(isOver){
  // 判断loading组件是否已经存在,不存在就创建一个
  if(!this.component){
  this.component = extendComponents(load)
  }
  // 创建加载组件
  this.loadMore&&this.loadMore()
  // 判断当前状态来控制loading的组件显示与否
  if(!this.isLoading){
  this.component.$el.remove()
  // 将loading组件置为空
  this.component = null
  }
 }
 },DEALY_TIME)
 window.addEventListener('scroll',fn)
},

详细代码

完整代码可以 点击查看 codepen 触底动画 关于上面代码中 extendComponents 方法的实现可以查看详细代码,也可以查看 Vue.extend 编程式插入组件

最后

将滚动触底的逻辑和 UI 都集成到 scroll.js 中,复用都方式可以放在 mixins 可以抽离成 v-directive,这样我们可以接受到绑定的 dom 不仅仅可以做 window 的滚动触底事件的判断,也可以 实现单个元素的滚动事件触底的监听 。后续可以在实现 v-directive 的版本。

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

相关文章

  • vue-cli3启动服务如何自动打开浏览器配置

    vue-cli3启动服务如何自动打开浏览器配置

    这篇文章主要介绍了vue-cli3启动服务如何自动打开浏览器配置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Vue使用new Blob()实现不同类型的文件下载功能

    Vue使用new Blob()实现不同类型的文件下载功能

    这篇文章主要给大家介绍了关于Vue使用new Blob()实现不同类型的文件下载功能的相关资料,在Vue项目中,经常用Blob二进制进行文件下载功能,需要的朋友可以参考下
    2023-07-07
  • Vue实现面包屑导航的正确方式

    Vue实现面包屑导航的正确方式

    面包屑导航(BreadcrumbNavigation)这个概念来自童话故事“汉赛尔和格莱特”,它的作用是告诉访问者他们在网站中的位置以及如何返回,本文为大家介绍了实现面包屑导航的正确方式,需要的可以参考一下
    2023-06-06
  • vue自定义气泡弹窗

    vue自定义气泡弹窗

    这篇文章主要为大家详细介绍了vue自定义气泡弹窗,包含css晃动动画shake制作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • vue使用高德地图实现添加点标记和获取点击位置信息的示例代码

    vue使用高德地图实现添加点标记和获取点击位置信息的示例代码

    这篇文章主要介绍了vue使用高德地图实现添加点标记和获取点击位置信息的示例代码,文中补充介绍了高德vue-amap使用(一)标记点位获取地址及经纬度,本文结合示例代码给大家介绍的非常详细,需要的朋友参考下吧
    2024-01-01
  • vue中改变了vuex数据视图不更新,也监听不到的原因及解决

    vue中改变了vuex数据视图不更新,也监听不到的原因及解决

    这篇文章主要介绍了vue中改变了vuex数据视图不更新,也监听不到的原因及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • vuex 解决报错this.$store.commit is not a function的方法

    vuex 解决报错this.$store.commit is not a function的方法

    这篇文章主要介绍了vuex 解决报错this.$store.commit is not a function的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • vue项目打包后上传至GitHub并实现github-pages的预览

    vue项目打包后上传至GitHub并实现github-pages的预览

    这篇文章主要介绍了vue项目打包后上传至GitHub并实现github-pages的预览,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • Vuex中五个属性以及使用方法详解

    Vuex中五个属性以及使用方法详解

    这篇文章主要给大家介绍了关于Vuex中五个属性以及使用的相关资料,Vuex是一个专为Vue.js应用程序开发的状态管理模式,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • nginx如何配置vue项目history的路由模式(非根目录)

    nginx如何配置vue项目history的路由模式(非根目录)

    这篇文章主要介绍了nginx如何配置vue项目history的路由模式(非根目录),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10

最新评论