Vue实现无限加载瀑布流
程序员文章站
2022-03-12 22:27:27
本文实例为大家分享了vue实现无限加载瀑布流的具体代码,供大家参考,具体内容如下我做的这个瀑布流放在了一个嵌套页面里,就是类似管理后台的main content中,如果要改成全屏的也很方便,其实更容易...
本文实例为大家分享了vue实现无限加载瀑布流的具体代码,供大家参考,具体内容如下
我做的这个瀑布流放在了一个嵌套页面里,就是类似管理后台的main content中,如果要改成全屏的也很方便,其实更容易些,因为会避开一些在元素上使用onscroll的坑。
通过这个瀑布流,可以掌握以下几个知识点:
1、在元素上监听scroll事件,相对直接在window上监听麻烦一点点;
2、image.onload事件;
3、promiseall;
4、vue 的 transition-group
这里使用了mockjs来模拟图片数据,然后通过axios来调用图片数据,也可使用其他数据源。
通过计算图片高度,判断把图片加载到哪一列。
如果屏幕还有空余,那就继续加载。
无限滚动加载。
屏幕resize这块没有做,后期可以加上去。
直接贴代码,有问题欢迎切磋。
<template> <div class="waterfall wf-wrap" ref="waterfall" @scroll="onscroll"> <ul> <transition-group name="list" tag="li"> <li v-for="(item,index) in waterfalllist" :key="index" class="wf-item" :style="{top:item.top+ 'px',left:item.left+'px', width:item.width+'px', height:item.height + 'px'}" > <img :src="item.src" /> </li> </transition-group> </ul> </div> </template> <script> import { getlist } from "@/api/demo"; export default { name: "waterfall", data() { return { waterfalllist: [], waterfallcol: 5, colwidth: 236, marginright: 10, marginbottom: 10, colheights: [], listquery: { page: 1, limit: 5, sort: "+id" }, loading: false, show: true }; }, mounted() { this.init(); }, methods: { init() { // 初始化时,每栏高度都为0 this.colheights = new array(this.waterfallcol); for (let i = 0; i < this.colheights.length; i++) { this.colheights[i] = 0; } this.colwidth = (this.$refs.waterfall.clientwidth - (this.waterfallcol - 1) * this.marginright) / this.waterfallcol; this.loadimgs(); }, loadimgs() { this.loading = true; // 从api获取数据 getlist(this.listquery).then(res => { let images = res.data.items; let promiseall = [], imgs = [], total = images.length; for (let i = 0; i < total; i++) { promiseall[i] = new promise(resolve => { imgs[i] = new image(); imgs[i].src = images[i].image_uri; imgs[i].onload = () => { let imgdata = {}; imgdata.height = (imgs[i].height * this.colwidth) / imgs[i].width; imgdata.width = this.colwidth; imgdata.src = images[i].image_uri; this.waterfalllist.push(imgdata); this.rankimgs(imgdata); resolve(imgs[i]); }; }); } promise.all(promiseall).then(() => { this.loading = false; this.loadmore(); }); }); }, loadmore() { if ( this.$refs.waterfall.clientheight + this.$refs.waterfall.scrolltop > this.filtermin().minheight && this.loading == false ) { this.loading = true; settimeout(() => { this.loadimgs(); }, 200); } }, rankimgs(imgdata) { let min = this.filtermin(); imgdata.top = min.minheight; imgdata.left = min.minindex * (this.colwidth + this.marginright); this.colheights[min.minindex] += imgdata.height + this.marginbottom; }, filtermin() { let minheight = math.min.apply(null, this.colheights); return { minheight: minheight, minindex: this.colheights.indexof(minheight) }; }, onscroll() { this.loadmore(); } } }; </script> <style lang="scss" scoped> ul li { list-style: none; } .wf-wrap { position: relative; width: 100%; height: 100%; overflow: scroll; } .wf-item { position: absolute; } .wf-item img { width: 100%; height: 100%; } .list-enter-active, .list-leave-active { transition: all 1s; } .list-enter, .list-leave-to /* .list-leave-active for below version 2.1.8 */ { opacity: 0; transform: translatey(30px); } </style>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。