vue滚动加载数据

在做移动端业务的时候,经常需要对数据进行滚动加载。所谓的滚动加载,其实就是像小程序那样的,触底加载数据。别听的字里行间听的那么高大上。其实并没有那么新鲜,也就是一个大家常见的功能。
滚动加载,它的主要逻辑就是监听winow的滚动事件,滚动到页面底部的时候执行数据请求的方法就完事了。
当然,对于滚动加截,常见的也就跟我们在PC端的分页的业务逻辑是一样的。滚动到底部的时候请求一次(或者在PC端来说是点击下一页),都是一样的意思。
然而,对于分页,我之前的博文也有介绍过,
下面,我这儿的是纯前端处理的滚动加载(也可以说是分页)都是一样的意思。

//了解下面的两个概念
document.documentElement.clientHeight //屏幕可视区域高度
document.documentElement.scrollHeight //浏览器所有内容高度
document.body.scrollTop || document.documentElement.scrollTop  //网页被卷去的高(可以理解为滚动条的高度)
data(){
	return {
		page: 1,//当前页
		totalPage:5, //每页记录
		messageContentSum:null,//总条数
		messageContent: [], //查出来的所有数据
		fenyeZhangShi: [], //分页展示(在模板中直接拿 这个来做循环 渲染即可 )
		params: null, //当前url的参数
		loading:false,
		fenge:false,
	}
}
methods:{
    getUrlParams(url) {
        // 通过 ? 分割获取后面的参数字符串
        let urlStr = url.split('?')[1]
        // 创建空对象存储参数
        let obj = {};
        // 再通过 & 将每一个参数单独分割出来
        let paramsArr = urlStr.split('&')
        for (let i = 0, len = paramsArr.length; i < len; i++) {
            // 再通过 = 将每一个参数分割为 key:value 的形式
            let arr = paramsArr[i].split('=')
            obj[arr[0]] = arr[1];
        }
        return obj
    },

	lazyLoading(e) {
	    //console.log(e)
	    let totalPageSum = Math.ceil((this.messageContentSum) / (this.totalPage)) //这儿得出来的结果就是一共有多少页, 【总条数 / 每页几条记录 】 注意 ceil
	    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop //滚动条高度
	    const clientHeight = document.documentElement.clientHeight //屏幕可视区域高度
	    const scrollHeight = document.documentElement.scrollHeight //浏览器所有内容高度
	    if (scrollTop + clientHeight >= scrollHeight) { //判断是否触底了
	        //console.log('触底')
	        //console.log(this.page , '当前页数') 
	        if (totalPageSum >= this.page) { //如果总页数大于或者等于当前页数
	            this.loading = true; //打开加载图标
	            setTimeout(() => { //给个定时器,让它 500 毫妙之后 对数据做处理
	                let totalArr = this.messageContent; //查出来的所有数据
	                let arr = []; // 先定义一个空数组,为下面的数据封装做准备
	                let start = (this.totalPage) * (this.page); //开始的数值,每一页的数量 * 当前页数 。 (由于每一页的数量是固定的,所以,第一次滚动到底的时候,当前页是初始的 1 。所以, 计算公式就是 每一页的数量 * 1 。 所以,第一次滚动到底的时候 开始的数值就是 每一页的数量)
	                let end = (this.totalPage) * (this.page) + (this.totalPage); // 结束数值, (每一页的数量 * 当前页数) + 每一页的数量  = 10
	                // 在次讲解下,可能这儿会太好理解
	                // start 因为页面刚加载进来,而且一页有5条数据。所以,如果滚动的话,数据是从第6条开始的。
	                // 所以,start 也就是从 第6条数据开始。而在代码世界里。数组是从0开始的。所以第6条数据,也就是索引是5,所有 每一页的数据5 * 当前页数1
	                // 因为开始是从第6条数据开始的,一页5条。那么,第2页就是 第6条到第10条 6,7,8,9,10 。
	                // 所以,第6条数据的数组索引就是 5,到结尾的索引就是9,
	                // 而尾就是 每一页的数量 * 当前页数 + 每一页的数量
	                for (var i = start; i < end; i++) {
	                    arr.push(totalArr[i]);
	                }
	                this.page = this.page + 1; //记住这儿,需要把当前的页数加上1 。因为每一次滚动到底的时候,已经加载了一页了。所以,当前页也需要对应的加上 1.
	                arr = arr.filter(Boolean); //这儿就是防止加载到最后一页了,并不是 每一页的倍数,在最后几个会出现undefined的情况,这个就是处理空数组用的。它的意思就是过滤到空数组
	                this.fenyeZhangShi = [...this.fenyeZhangShi, ...arr]; //最后就是组装数据,把最开始从后端请求的每一页数据和现在刚刚滚动到底加载出来数组组装到一起返回给模板中使用。
	                this.loading = false; //最后别忘了关闭加截图标
	            }, 500)
	            
	        } else {
	            this.fenge = true; //如果滚动到底已经没有可加截的数据了,那就需要在这儿做一个处理。
	            console.log('没有更多了');
	        }
	    }
	},

    getCenter() {
        let data = {}; //请求后端接口所需要的参数
        let url = '';
        axios.get(url, { params: data })
            .then(res => {
            	let totalPage = this.totalPage; //规定每页的条数
                //console.log(res);
                let { data } = res; //这儿就是后端返回的数据,(是所有的数据,因为分页是纯前端处理的。所以,后端只需要返回一大堆(所有)的数据就可以。)
                //console.log(data);
                this.messageContentSum = data.length; //计算总共有多少条数据
                if (this.messageContentSum <= totalPage) { //如果说 后端返回的数据 少于或者等于 每页规定的数量,那就不需要做分页处理了
                    this.fenyeZhangShi = data
                } else {
                    this.messageContent = data; //如查后端返回的数据超过每页规定的灵敏据,那就需要做分页
                    let arr = [];
                    for (var i = 0; i < totalPage; i++) {
                        arr.push(data[i]);
                    }
                    this.fenyeZhangShi = arr
                }
            })
    },


}                    	
mounted() {
	var domain = window.location.href; //获取当前url
	let params = this.getUrlParams(domain); //获取当前url的参数(获取到的是一个对象)
	this.params = params;
	this.getCenter(); //这儿请求后端接口的方法
	window.addEventListener('scroll', this.lazyLoading); //监听滚动事件,注意这儿监听的方法不需要括号
},

以上的的都是纯前端处理了。当然,实际中,也还会遇上在后端。在后端处理,也是一样的道理。每一次滚动到底的时候就请求一次接口。下面是后端处理的,前端只需要在滚动到底的时候请求一次接口即可。

data(){
	return {
		page: 1,//当前页
		totalPage:5, //每页记录
		fenyeZhangShi: [], //分页展示(在模板中直接拿 这个来做循环 渲染即可 )
		loading:false,
		fenge:false,
	}
}
methods:{
	async lazyLoading(e) {
	    //console.log(e)
	    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
	    const clientHeight = document.documentElement.clientHeight
	    const scrollHeight = document.documentElement.scrollHeight
	    if (scrollTop + clientHeight >= scrollHeight) { //判断是否触底了
	    	this.loading = true; //打开加载图标
	    	this.page = this.page + 1; //记住滚动到底的时候,当前页需要加1
	    	let arr = await this.getCenter();
	    	this.fenyeZhangShi = [...this.fenyeZhangShi, ...arr]
	    }
	},


	async getCenterList(){
		this.fenyeZhangShi = await this.getCenter();
	},
	getCenter(){ //ajax请求的方法
		return new Promise((resolve,reject)=>{
			let data = {
				page:this.page, //当前页码,第一次进来是 1,之后每一次滚动到底就会加1
				totalPage:this.totalPage, //每页显示的数量
			};
	        let url = '';
	        axios.get(url, { params: data })
	            .then(res => {
	                //console.log(res);
	                let { data } = res; //这儿就是后端返回的数据,(是一部份数据,页面刚进来就是第1次的数据,之后滚动之后就会做出改变)
	                resolve(data)
	            })
		})
	},
}                    	
mounted() {
	this.getCenterList(); //这儿请求后端接口的方法
	window.addEventListener('scroll', this.lazyLoading); //监听滚动加载,注意这儿监听的方法不需要括号
},

关联文档 【https://www.cnblogs.com/web-wjg/p/7349586.html】

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值