您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

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

51自学网 2022-05-02 21:34:58
  javascript

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加载数据内容请搜索wanshiok.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持wanshiok.com!


JS实现猜拳游戏
vue时间线组件的使用方法
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1