zoukankan      html  css  js  c++  java
  • 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{
         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;
                 100%;
                li{
                     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 
     
     
     
  • 相关阅读:
    【记录】Mybatis-Generator 数据层代码生成器,自动生成dao类,mapper,pojo类
    【记录】logstash 的filter 使用
    【转载】windows 开启 nginx 监听80 端口 以及 禁用 http 服务后,无法重启 HTTP 服务,提示 系统错误 123,文件目录、卷标出错
    【报错】解决logstash tracking_column not found in dataset. {:tracking_column=>"updated_time"}问题
    【记录】elasticsearch 注解
    index read-only
    wget下载阿里云RDS备份集
    mysqlbinlog相关
    es安装elasticsearch-sql插件
    elastichd安装部署
  • 原文地址:https://www.cnblogs.com/muamaker/p/11345557.html
Copyright © 2011-2022 走看看