亲宝软件园·资讯

展开

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

JackieDYH 人气:0
想了解Vue向下滚动加载更多数据scroll案例详解的相关内容吗,JackieDYH在本文为您仔细讲解Vue加载数据的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:vue加载更多数据,vue,滚动加载,下面大家一起来学习吧。

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条。就如下图:

 

选项解释

其他选项:

实战应用

可以看到,上方的例子是在不断的修改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)
            },

上拉加载更多

//下拉触发
 
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方法。

条件用法

<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),

加载全部内容

相关教程
猜你喜欢
用户评论