Vue向下滚动加载更多数据scroll案例详解

vue-infinite-scroll

安装

npm install vue-infinite-scroll --save

尽管官方也推荐了几种载入方式,但“最vue”的方式肯定是在main.js中加入

import infiniteScroll from 'vue-infinite-scroll'
Vue.use(infiniteScroll)

实现范例

官方给的代码范例是假设你在根组件写代码,实际上我们肯定是在子组件里写代码,所以代码也需要略作修改,下方只列有用的代码片段:

<div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
    <div v-for="item in data" :key="item.index">{{item.name}}</div>
</div>
 data () {
    return {
      count: 0,
      data: [],
      busy: false
    }
  }
methods: {
    loadMore: function() {
      this.busy = true
      setTimeout(() => {
        for (var i = 0, j = 10; i < j; i++) {
          this.data.push({name: this.count++ })
        }
        console.log(this.data)
        this.busy = false
      }, 1000)
    }
  }

效果

默认会载入10行数据,只要往下滚动到页面底部,就会在1秒后再次加载10条,然后继续滚动,又会加载10条。就如下图:

选项解释

  • v-infinite-scroll="loadMore"表示回调函数是loadMore
  • infinite-scroll-disabled="busy"表示由变量busy决定是否执行loadMorefalse则执行loadMoretrue则不执行,看清楚,busy表示繁忙,繁忙的时候是不执行的。
  • infinite-scroll-distance="10"这里10决定了页面滚动到离页尾多少像素的时候触发回调函数,10是像素值。通常我们会在页尾做一个几十像素高的“正在加载中...”,这样的话,可以把这个div的高度设为infinite-scroll-distance的值即可。

其他选项:

  • infinite-scroll-immediate-check 默认值为true,该指令意思是,应该在绑定后立即检查busy的值和是否滚动到底。如果你的初始内容高度不够高、不足以填满可滚动的容器的话,你应设为true,这样会立即执行一次loadMore,会帮你填充一些初始内容。
  • infinite-scroll-listen-for-event 当事件在Vue实例中发出时,无限滚动将再次检查。
  • infinite-scroll-throttle-delay 检查busy的值的时间间隔,默认值是200,因为vue-infinite-scroll的基础原理就是,vue-infinite-scroll会循环检查busy的值,以及是否滚动到底,只有当:busy为false且滚动到底,回调函数才会执行。

实战应用

可以看到,上方的例子是在不断的修改data变量,data变量的数据不断增加,这看起来是没错的。但是,实战中,我们的新数据肯定是Ajax获取的,并不是范例中的用for循环来灌入无用的自然数,而且,并不需要setTimeout,我们希望的是页面滚动到底部就立即执行Ajax,事实上,上面代码中的setTimeout只是为了模拟一个延迟加载的效果,并不是说必须要延迟1秒才Ajax。

实战中该怎么做?

只需要将这段模拟Ajax的代码改为真正的Ajax获取数据的代码即可:

 setTimeout(() => {
        for (var i = 0, j = 10; i < j; i++) {
          this.data.push({name: this.count++ })
        }
        console.log(this.data)
        this.busy = false
      }, 1000)

另外,this.busy = false也必须作为Ajax的回调


vue-scroller

安装

npm install vue-scroller -d

在main.js里面使用

import VueScroller from 'vue-scroller'
Vue.use(VueScroller)

使用

注意:scroller的使用最好设置一个高

<scroller style="top: 100px;" :height='400' :on-refresh="refresh" :on-infinite="infinite" ref="myscroller">
     <div class="order-box" v-for="(item,index) in orderList" :key="index">

     </div>
 </scroller>

数据

data(){
           return{
                status:'all',
                orderList:[],
                page:0,
                all_page:1,
            }
        },

下拉刷新

refresh (done) {
                setTimeout(()=>{
                    done();
                },1500)
            },

上拉加载更多

  • 注意:done的使用,如果在数据没有赋值到模板前就调用,就会一直触发下拉函数,所以我们要在请求成功的回调中模板赋值后调用
  • 下拉的函数是绑定属性的方式绑定在scroller标签上的,所以我们不需要在created里面调用一次请求函数,页面初始化的时候回自动调用一次下拉的函数,从而获取到第一页的数据
//下拉触发

infinite (done) {
                if(this.page>=this.all_page){
                    setTimeout(()=>{
                        this.$refs.myscroller.finishInfinite(true);
                    },1500)
                }else{

                    setTimeout(()=>{
                        this.page++;
                        this.getorderList(done)

                    },500);
                }
            },

getorderList(done){
                this.$http({
                    method:'post',
                    url:'/seckill/server/orderList',
                    data:{
                        jwt:this.jwt,
                        status:this.status,
                        page:this.page,
                        page_size:5
                    }
                }).then(res=>{
                    if(res.data.code == 0){

                        this.orderList.push.apply(this.orderList,res.data.data.list)
                        this.$refs.myscroller.finishInfinite(true)

                        this.page = res.data.data.page
                        this.all_page = res.data.data.all_page
                        done();
                    }else{

                    }
                })
            },

注意

如果涉及到tab栏切换,需要重新设置scroller的状态.finishInfinite(false)参数为false时会从新调用一次上拉函数,从而重置当前scroller的状态

goodsAll(){
                this.status = 'all'
                this.page = 0
                this.all_page = 1
                this.$refs.myscroller.finishInfinite(false);
                this.orderList = []
            },

triggerPullToRefresh() 触发下拉刷新

finishPullToRefresh() 完成下拉刷新

this.$refs.my_scroller.finishInfinite(false)
finishInfinite(isNoMoreData :Boolean) 当参数为false时,上拉获取数据可以重新调用。当参数为true,上拉获取数据回调函数停止使用,下拉下部不再显示loading,会显示‘'暂无更多数据


vue-infinite-loading

安装

npm install vue-infinite-loading --save

组件内使用

// 组件类使用
import InfiniteLoading from 'vue-infinite-loading';

export default {
  components: { InfiniteLoading }
}

//使用 基础版
<infinite-loading
  spinner="spiral"
  @infinite="infiniteHandler"
  :distance="200"
  class="infinite-loading-wrap"
>
  <!-- <div slot="spinner">Loading...</div> -->
  <div slot="no-more">No more Data</div>
  <div slot="no-results">No results Data</div>
  <!-- <div slot="error" slot-scope="{ trigger }">
	Error Data, click <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  @click="trigger">here</a> toretry
  </div> -->
</infinite-loading>

基本用法

<template>
  <div>     
		<p v-for="(item,index) in list" :key="index">      
			<span v-text="item"></span>     
		</p>     
		<!--infinite-loading这个组件要放在列表的底部,滚动的盒子里面!-->
		<infinite-loading
			spinner="spiral"
			@infinite="infiniteHandler"
			:identifier="infiniteId"
			:distance="200"
			class="infinite-loading-wrap"
		>
			<div slot="spinner">Loading...</div>
			<div slot="no-more">No more Data</div>
			<div slot="no-results">No results Data</div>
			<div slot="error" slot-scope="{ trigger }">
			  Error Data, click <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  @click="trigger">here</a> toretry
			</div>
		</infinite-loading>  
	</div>
</template>

<script>  
import InfiniteLoading from 'vue-infinite-loading';
  export default {
    data() {
      return {
		  infiniteId: +new Date(), // 重置滚动状态 改变
		  page: 1,
        list: []
      };
    },
    methods: {
		// 重置滚动状态
		rest(){
		  this.list = [];
		  this.page = 1;
		  this.infiniteId += 1;
		},
      async infiniteHandler($state) {
			// 模仿请求数据
			const res = await this.$axios.workList({ page: this.page, pagesize: 20 });
			  if (res.data.list.length) {
				this.page += 1;
				this.list = this.list.concat(res.data.list);
				$state.loaded();
			  } else {
				$state.complete();
			  }
        // 这里模仿加载延迟1秒钟
        //setTimeout(() => {
         // let temp = [];
         // for (let i = this.list.length + 1; i <= this.list.length + 20; i++) {
          //  temp.push(i);
         // }
         // this.list = this.list.concat(temp);
         // $state.loaded();
        //}, 1000);
        //},
    },
    components: { InfiniteLoading }
  }
</script>

分页用法

<template>
  <div>
    <ul>
      <li class="hacker-news-item" v-for="(item, key) in list"></li>
    </ul>
    <infinite-loading @infinite="infiniteHandler">
      <span slot="no-more">No more Data</span>
    </infinite-loading>
  </div>
</template>    

<script>
import InfiniteLoading from "vue-infinite-loading";
import axios from "axios";
export default {
  data() {
    return {
      list: [],
    };
  },
  methods: {
    infiniteHandler($state) {
      let api = "http://xxx.com/xxx"; // api为你请求数据地址
      axios
        .get(api, {
          params: {
            // 页码参数(10条每页)
            page: this.list.length / 10 + 1,
          },
        })
        .then((response) => {
          if (response.data.length) {
            // response.data为你请求接口返回的数组列表
            this.list = this.list.concat(response.data);
            $state.loaded();
            if (this.list.length / 10 === 10) {
              // 这里是加载了10页数据,设置不在加载
              $state.complete();
            }
          } else {
            $state.complete();
          }
        });
    },
  },
  components: { InfiniteLoading },
};
</script>

说明: $state: 该组件会传递一个特殊的事件参数$state给事件处理器来改变加载状态,$state参数包括三个方法,它们是loaded方法,complete方法和reset方法。

  • loaded方法用于在每次加载数据后停止播放动画,然后该组件将准备好进行下一次触发。
  • complete方法用于完成完整的无限加载,则该组件将不再处理任何滚动操作。如果在loaded调用complete方法时永远不会调用该方法,则此组件将显示用户的结果消息,如果不是,则将显示不再有用户消息,并且可以按slot设置其它内容
  • reset方法是将组件返回到原来的状态

条件用法

<template>
    <div class="hacker-news-list">
          <div class="hacker-news-header">
            <!--下拉改变-->
            <select v-model="tag" @change="changeFilter()">
                  <option value="story">Story</option>
                  <option value="history">History</option>
            </select>
              <!--或者点击改变-->
            <button @click="changeFilter()">搜索</button>
          </div>
          <ul>
              <li class="hacker-news-item" v-for="(item, key) in list"></li>
           </ul>
           <!--不要忘记设置这个 ref="infiniteLoading"-->
          <infinite-loading @infinite="infiniteHandler" ref="infiniteLoading">
            <span slot="no-more">No more data</span>
          </infinite-loading>
    </div>
</template>

<script>
    import InfiniteLoading from 'vue-infinite-loading';
    import axios from 'axios';

    export default {
          data() {
            return {
                  list: [],
                  tag: 'story',
            };
          },
          methods: {
            infiniteHandler($state) {
                  const api="http://xxx.com/xxx";
                  // api为你请求数据地址
                  axios.get(api, {
                    params: {
                        // 改变的条件参数
                          tags: this.tag,
                          page: this.list.length / 10 + 1,
                    },
                  }).then(({ data }) => {
                    if (data.result.length) {
                          this.list = this.list.concat(data.result);
                          $state.loaded();
                          if (this.list.length / 20 === 10) {
                            state.complete();
                          }
                    } else {
                          $state.complete();
                    }
                  });
            },
            //改变条件条用此方法
            changeFilter() {
                  this.list = [];
                  this.$nextTick(() => {
                    this.$refs.infiniteLoading.$emit('$InfiniteLoading:reset');
                  });
            },
          },
          components: { InfiniteLoading }
    }
</script>


防抖

import { debounce } from "lodash"; // 防抖

// 防抖
get: debounce(async function () {
  let k = await this.$axios.getList_API();
  console.log(k, "防抖版");
}, 1000),

到此这篇关于Vue向下滚动加载更多数据-scroll-案例的文章就介绍到这了,更多相关Vue加载数据内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Javascript vue.js表格分页,ajax异步加载数据

    分页一般和表格一起用,分页链接作为表格的一部分,将分页链接封装成一个独立的组件,然后作为子组件嵌入到表格组件中,这样比较合理. 效果: 代码: 1.注册一个组件 js Vue.component('pagination',{ template:'#paginationTpl', replace:true, props:['cur','all','pageNum'], methods:{ //页码点击事件 btnClick: function(index){ if(index != this.cu

  • 详解使用Vue.Js结合Jquery Ajax加载数据的两种方式

    整理文档,搜刮出一个使用Vue.Js结合Jquery Ajax加载数据的两种方式的代码,稍微整理精简一下做下分享. 废话不多说,直接上代码 html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo</title> <script src="js/jquery.js"

  • vue 使用鼠标滚动加载数据的例子

    关于用鼠标滚动到某个位置我们就去加载数据,这样的场景与业务需求现在越来越常见,现在来分析下<vue.js 实战>中作者的一个解决策略: 1. 设置一个标志位用来判断数据是否在加载中 2. 将滚动区域设置成 overfow:auto(显示滚动条) 3. 给滚动区域加入监听事件并绑定ref属性 来获取DOM实例 4. 当鼠标滚动到底部时,加载数据 4.1 如果此时 标志位为true则 直接退出,不进行此时数据加载 关键代码如下: <template> //...代码省略 //该div

  • Vue实现下拉滚动加载数据的示例

    目录 第一步:安装 第二步:引用 第三步:使用 Web项目经常会用到下拉滚动加载数据的功能,今天就来种草 Vue-infinite-loading这个插件,讲解一下使用方法! 第一步:安装 npm install vue-infinite-loading --save 第二步:引用 import InfiniteLoading from 'vue-infinite-loading'; export default { components: { InfiniteLoading } } 第三步:使

  • Vue下滚动到页面底部无限加载数据的示例代码

    看到一篇Implementing an Infinite Scroll with Vue.js, 觉得挺实用的就看了下, 顺便简单翻译了一下给需要的人参考. 从这个项目中可以加深对Vue的生命周期的理解, 何时开始axios请求, 如何结合Vue使用原生js来写scroll事件等等, 我这里主要是对原文的重点提取和补充 本文技术要点 Vue生命周期 axios简单用法 moment.js格式化日期 图片懒加载 结合原生js来写scroll事件 请求节流 创建项目 首先创建一个简单的vue项目 #

  • vue.js 表格分页ajax 异步加载数据

    Vue.js是一个轻巧.高性能.可组件化的MVVM库,同时拥有非常容易上手的API. 分页一般和表格一起用,分页链接作为表格的一部分,将分页链接封装成一个独立的组件,然后作为子组件嵌入到表格组件中,这样比较合理. 1.注册一个组件 js Vue.component('pagination',{ template:'#paginationTpl', replace:true, props:['cur','all','pageNum'], methods:{ //页码点击事件 btnClick: f

  • Vue向下滚动加载更多数据scroll案例详解

    vue-infinite-scroll 安装 npm install vue-infinite-scroll --save 尽管官方也推荐了几种载入方式,但"最vue"的方式肯定是在main.js中加入 import infiniteScroll from 'vue-infinite-scroll' Vue.use(infiniteScroll) 实现范例 官方给的代码范例是假设你在根组件写代码,实际上我们肯定是在子组件里写代码,所以代码也需要略作修改,下方只列有用的代码片段: <

  • vue中实现滚动加载更多的示例

    在以前的前端刀耕火种时代要实现滚动加载更多想要大家都是很快实现了,在vue会有一点麻烦,最近自己研究了一下,做了一个简单的demo,供大家参考: <template> <div> <ul> <li v-for="item in articles"> <h2>{{item.title}}</h2> <img :src="item.images" alt=""> &l

  • Angularjs 滚动加载更多数据

    下面的例子只是为了简单记录怎么使用angularjs来实现滚动加载数据,具体的还是需要具体看待: Javascript部分的controller app.controller('AnalysizerCtrl', ['$scope', '$timeout', '$window', function ($scope, $timeout, $window) { $scope.showData = false; $scope.isLoadingPIG = false; $scope.isLoadingU

  • ASP.NET仿新浪微博下拉加载更多数据瀑布流效果

    闲来无事,琢磨着写点东西.貌似页面下拉加载数据,瀑布流的效果很火,各个网站都能见到各式各样的展示效果,原理大同小异.于是乎,决定自己写一写这个效果,希望能给比我还菜的菜鸟们一点参考价值. 在开始之前,先把实现的基本原理说一下.当夜幕下拉到底部的时候,js可以判断滚动条的位置,到达底部触发js方法,执行jquery的ajax方法,向后台一般处理程序夜幕ashx文件请求数据源,得到json格式的数据源.然后,遍历json数据源,拼接一个li标签,再填充到页面上去. 首先,我们来做个简单的html页面

  • Vue实现下拉加载更多

    熟悉Element-UI的开发者可能都会有这样的经历,它的无限滚动 InfiniteScroll 并不好用,下面介绍两种下拉加载的实现方法: 1. 使用el-table-infinite-scroll 插件 (1). 安装插件 npm install --save el-table-infinite-scroll (2). 全局引入并注册 // main.js import elTableInfiniteScroll from 'el-table-infinite-scroll'; Vue.us

  • Vue使用Three.js加载glTF模型的方法详解

    前言 Three.js是一个跨浏览器的脚本,使用JavaScript函数库或API来在网页浏览器中创建和展示动画的三维计算机图形,基于WebGL实现,对WebGL进行了进一步的封装,简化了多数复杂的接口. Three.js支持包括 .obj..gltf等类型的模型结构.glTF(GL传输格式)是Khronos的一个开放项目,它为3D资产提供了一种通用的.可扩展的格式,这种格式既高效又与现代web技术高度互操作. obj格式的模型只支持顶点.法线.纹理坐标和基本材质,而glTF模型除上述所有内容外

  • vue+webpack实现异步加载三种用法示例详解

    1.第一例 const Home = resolve => { import("@/components/home/home.vue").then( module => { resolve(module) } } 注:(上面import的时候可以不写后缀) export default [{ path: '/home', name:'home', component: Home, meta: { requireAuth: true, // 添加该属性可以判断出该页面是否需要

  • jQuery模拟原生态App上拉刷新下拉加载更多页面及原理

    很多App中,新闻或者展示类都存在下拉刷新和上拉加载的效果,网上提供了实现这种效果的第三方类(详情请见MJRefresh和EGOTableViewPullRefresh),用起来很方便,但是闲暇之余,我们可以思考下,这种效果实现的原理是什么,我以前说过,只要是动画都是骗人的,只要不是硬件问题大部分效果都能在系统UI的基础上做出来. 下面通过jQuery手机端上拉下拉刷新页面代码,很像QQ空间客户端或者微信下拉刷新页面特效代码. 请看下面效果图: 在线预览    源码下载 html代码: <div

  • Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法

    通过多次爬坑,发现了这些监听滚动来加载更多的组件的共同点, 因为这些加载更多的方法是绑定在需要加载更多的内容的元素上的, 所以是进入页面则直接触发一次,当监听到滚动事件之后,继续加载更多, 所以对于无限滚动加载不需要写首次载入列表的函数, 代码如下: html: //父组件 <div v-infinite-scroll="loadMore" infinite-scroll-disabled="loading" infinite-scroll-distance=

  • 通过原生vue添加滚动加载更多功能

    这篇文章主要介绍了通过原生vue添加滚动加载更多功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 vue中添加滚动加载更多,因为是单页面所以需要在跳出页面时候销毁滚动,要不会出现错乱.我们在mounted建立滚动,destroyed销毁滚动. mounted () { window.addEventListener('scroll', this.handleScroll) }, destroyed () { window.removeEven

随机推荐