vue 写一个瀑布流插件 - muamaker

vue

vue 写一个瀑布流插件

2019-08-13 14:09 

muamaker 

阅读(1624) 

评论(0) 

编辑 

收藏 

举报

效果如图所示:

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

新建 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 

 

 

 

以上是 vue 写一个瀑布流插件 - muamaker 的全部内容, 来源链接: utcz.com/z/374963.html

回到顶部