uniapp-小程序-瀑布流布局-支持下拉刷新上拉加载更多

uniapp-小程序-瀑布流布局-支持下拉刷新上拉加载更多

主要思路:

  • 将父组件传递进来的list分为两组,leftList和rightList,初始化为空数组
  • 页面布局分为左右两侧,左侧渲染leftList的数据,右侧渲染rightList的数据,并初始化左右两栏的高度为0
  • 利用image标签中的load事件,在图片加载的时候,获取到图片的实际尺寸,计算出要显示的高度。比较两栏的高度,将对应的数据加到leftList或者rightList

我们在组件中写一个两列的布局,图片的宽度设定为345rpx,文字的高度定为100rpx,下边距定为20rpx,给image绑定一个load方法,onImageLoad,这个组件的核心就是这个方法。

//wterfall




可以看到,上面有两个view,分别是left和right,分别渲染的是leftList和rightList里面的数据,那么这两个数据是怎么来的呢?我们在组件中定义一个prop:

props: {
        list: {
            type: Array,
            default: []
        }
}

这个list是通过父组件传递过来的,也就是你原始的数据,我们在组件中再声明几个变量,并在created的时候,将list中的第一个数据存入到leftList中

data() {
        return {
            leftList: [],
            rightList: [],
            itemIndex: 0,
            leftHeight: 0,
            rightHeight: 0
        };
},
created() {
        this.leftList = [this.list[0]]; //第一张图片入栈
},

然后就是最重要的onImageLoad方法了

onImageLoad(e) {
            if (!e) {
                console.log('无图片!!!!');
                return;
            }
            let imgH = (e.detail.height / e.detail.width) * 345 + 100 + 20; //图片显示高度加上下面的文字的高度100rpx,加上margin-bottom20rpx
            let that = this;
            if (that.itemIndex === 0) {
                that.leftHeight += imgH; //第一张图片高度加到左边
                that.itemIndex++;
                that.rightList.push(that.list[that.itemIndex]); //第二张图片先入栈
            } else {
                that.itemIndex++;
                //再加高度
                if (that.leftHeight > that.rightHeight) {
                    that.rightHeight += imgH;
                } else {
                    that.leftHeight += imgH;
                }
                if (that.itemIndex < that.list.length) {
                    //下一张图片入栈
                    if (that.leftHeight > that.rightHeight) {
                        that.rightList.push(that.list[that.itemIndex]);
                    } else {
                        that.leftList.push(that.list[that.itemIndex]);
                    }
                }
            }
    }

上面注释的也比较清楚了,首先要将第一张图入栈,这个时候onImageLoad才会返回图片信息,不然的话是没有图片的,在onImageLoad方法执行的时候,先计算出图片的显示高度,然后计算leftHeight和rightHeight的高度,再将下一张图入栈。

上拉加载更多、下拉刷新

上拉加载更多的时候,监听list的变化,list的新的值会比旧的值length更大,这个时候将新添加进来的值的第一个数据先入栈,相当于是首次加载的时候第一个数据先放到leftList。

    watch: {
        list(n, o) {
            let that = this;
            // console.log('=====watch  list=====', n, o);
            let ol = o.length;
            let nl = n.length;
            if (nl > ol) {
                if (this.leftHeight > this.rightHeight) {
                    that.rightList.push(that.list[ol]);
                } else {
                    that.leftList.push(that.list[ol]);
                }
                this.onImageLoad();
            }
        }
    },

下拉刷新的时候有一点不一样,需要先将组件销毁掉,再重新渲染,可以在父组件中用v-if判断是否要销毁,父组件中的代码:



onPullDownRefresh() {
        this.goodsList = [];
        setTimeout(() => {
            this.goodsList = [...list];
        }, 500);

        uni.stopPullDownRefresh();
}

大致就是这样,我觉得还不够好,但在我的项目中也是够用了,贴上完整的代码:

//waterfall.vue









    

你可能感兴趣的:(uniapp-小程序-瀑布流布局-支持下拉刷新上拉加载更多)