您的当前位置:首页正文

通过vue写一个瀑布流插件代码实例

2020-11-27 来源:帮我找美食网

这篇文章主要介绍了通过vue写一个瀑布流插件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

效果如图所示:

采用了预先加载图片,再计算高度的办法。网络差的情况下,可能有点卡

新建 vue-water-easy.vue 组件文件

<template>
 <div class="vue-water-easy" ref="waterWrap">
 <div v-for="(items,clos) in list" :key="clos" :style="waterStyle" class="colsW">
 <ul>
 <li v-for="(item,index) in items" :key="index" :style="{marginBottom:gap+'px'}">
 <slot :item="item" :index="index" :clos="clos"></slot>
 </li>
 </ul>
 </div>
 </div>
</template>
<script>
 
export default {
 props:{
 maxCols:{
 type:Number,
 default:3,
 validator(value){
 return value > 1;
 }
 },
 srcKey:{
 type:String,
 default:"src"
 },
 gap:{
 type:Number,
 default:10,
 validator(value){
 return value > 0;
 }
 },
 imgsArr:{
 type:Array,
 required:true
 }
 },
 computed:{
 waterStyle(){
 if(this.gap <= 0){
 this.gap = 10;
 }
 return {
 margin:`0 ${this.gap/2}px`
 }
 }
 },
 watch:{
 imgsArr(val){
 this.$nextTick(()=>{
 this.list = this.initData();
 this.start(0);
 })
 }
 },
 data(){
 let list = this.initData();
 return {
 list:list
 }
 },
 mounted(){
 this.start(0);
 },
 methods:{
 initData(){
 let list = new Array(this.maxCols);
 for(let i = 0; i < this.maxCols ; i++){
 list[i] = [];
 }
 return list;
 },
 start(i){
 const me = this;
 let imgsArr = me.imgsArr;
 if(i >= imgsArr.length && this.$refs.waterWrap){
 return ;
 }
 me.loadImg(imgsArr[i],i).catch(()=>{
 }).finally(()=>{
 me.start(++i);
 });
 // for(let i = 0; i < imgsArr.length; i++ ){
 // let item = imgsArr[i];
 // me.loadImg(item,i);
 // }
 },
 loadImg(item){
 const me = this;
 let srcKey = me.srcKey;
 return new Promise(function(resolve,reject){
 if(item && item[srcKey]){
 let src = item[srcKey];
 let img = new Image();
 img.src = src;
 img.crossOrigin = "anonymous";
 img.onload = function(){
 var index = me.getMinHeight();
 me.list[index].push(item);
 me.$nextTick(()=>{
 resolve(img)
 });
 }
 img.onerror = function(e){
 reject(e);
 }
 }else{
 reject('数据错误');
 }
 })
 
 },
 getMinHeight(){
 let index = 0;
 try{
 if(!this.$refs.waterWrap){
 return index;
 }
 let childs = this.$refs.waterWrap.children || [];
 let minx = childs[0].children[0].offsetHeight;
 for(let i = 1; i < childs.length; i++){
 let element = childs[i];
 let h = element.children[0].offsetHeight;
 if(h < minx){
 minx = h ;
 index = i;
 }
 }
 }catch(e){
 console.warn(e);
 return index;
 }
 
 return index;
 } 
 }
}
</script>
<style lang="scss" scoped>
.vue-water-easy{
 width: 100%;
 display: flex;
 justify-content: space-between;
 div.colsW{
 flex: 1;
 box-sizing: border-box;
 position: relative;
 &:last-child{
 margin-right: 0 !important;
 }
 &:first-child{
 margin-left: 0 !important;
 }
 ul{
 list-style: none;
 width: 100%;
 li{
 width: 100%;
 }
 }
 } 
}
</style>

使用

<vueWaterEasy :imgsArr="imgsArr" srcKey="url">
 <template v-slot="{item}">
 <img :src="item.url" alt="">
 </template>
</vueWaterEasy>

imgsArr:为图片数据的数组,内部包含对象 [ { src:"xxxx" } ]

srckey : 为图片路径的属性,默认为 src

maxCols: 多少列 默认为 3

gap : 每列的间距默认 10px

显示全文