欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-11-11 15:55:22
这篇文章主要介绍了通过vue写一个瀑布流插件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 效果如图所示:...

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

效果如图所示:

通过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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。