自学内容网 自学内容网

瀑布流实现uniapp,适用与微信小程序

使用uniapp插件,这个是微信小程序最不卡的,其他微信小程序都有点卡顿

瀑布流布局-waterfall - DCloud 插件市场

这个地方需要改一下,要不然会导致下拉刷新不出来

import Waterfall from "@/uni_modules/helang-waterfall/components/waterfall/waterfall-list";

使用办法

<template>
    <view style="padding: 20rpx 0;">
        <waterfall ref="helangWaterfall" :hideList="hideList" imageKey="imgUrl" @statusChange="handleStatusChange">
            <template v-slot:default="{ list, colWidth }">
                <waterfall-col v-for="(colItem, colIndex) in list" :key="colIndex" :colWidth="colWidth">
                    <waterfall-item v-for="(item, index) in colItem" :key="item.__waterfall_renderId"
                        :colIndex="colIndex" @height="onRenderHeight">
                        <view class="content" @click="handleToDetail(item)" :data-col_index="colIndex" :data-item_index="index">
                            <image class="image" mode="aspectFill" :src="item.imgUrl"
                                :style="{ height: item.__waterfall_imageHeight }">
                            </image>
                            <view class="personal-title">{{ item.title }}</view>
                            <view class="personal-fun">
                                <view class="personal-l">
                                    <view class="personal-user">
                                        <image :src="item.user.avatarUrl" />
                                        <view class="user-name">{{ item.user.nickName }}</view>
                                    </view>
                                </view>
                                <view class="personal-r" @click.stop="handleLike(item)">
                                    <view class="iconfont icon-aixin2 no" v-if="getZan(item)"></view>
                                    <view class="iconfont icon-aixin3 yes" v-else></view>
                                    <view class="personal-likes">{{ getLinkes(item) }}</view>
                                </view>
                            </view>
                        </view>
                    </waterfall-item>
                </waterfall-col>
            </template>
            <template #tips>
                <view class="load-txt">
                    <view v-if="hideList">
                        <block v-if="waterfall.status == 'empty'">
                            <u-empty text="暂无相关数据" mode="list"></u-empty>
                        </block>
                    </view>
                    <view v-else-if="waterfall.status == 'nomore'" style="padding-top: 30rpx;">我也是有底线的</view>
                    <view v-else style="padding-top: 30rpx;">加载中</view>
                </view>
            </template>
        </waterfall>
    </view>
</template>

<script>
// 瀑布流组件
import Waterfall from "@/uni_modules/helang-waterfall/components/waterfall/waterfall-list";
import WaterfallCol from "@/uni_modules/helang-waterfall/components/waterfall/waterfall-col";
import WaterfallItem from "@/uni_modules/helang-waterfall/components/waterfall/waterfall-item";
export default {
    components: {
        "waterfall": Waterfall,
        "waterfall-col": WaterfallCol,
        "waterfall-item": WaterfallItem
    },
    computed: {
        hideList() {
            return ['fail', 'empty'].includes(this.waterfall.status);
        }
    },
    data() {
        return {
            zanId: [],
            // 异步请求相关
            ajax: {
                // 是否可以加载
                load: true,
                // 页码
                page: 1,
                // 数据列表
                dataList: []
            },
            // 瀑布流组件相关
            waterfall: {
                // 组件状态
                status: '',
                // 是否渲染完成
                renderEnd: true
            },
            loadStatus: 'loadmore'
        }
    },
    methods: {
        getLinkes(item){
            let linkes = item.likes;
            if(this.zanId.includes(item.dynamic_id)){
                linkes = linkes + 1;
            }
            return linkes
        },
        getZan(item){
            let zan = true;
            if(this.zanId.includes(item.dynamic_id)){
                zan = false
            }
            return zan
        },
        // 下拉刷新
        pullDownRefresh() {
            setTimeout(() => {
                uni.stopPullDownRefresh();
                this.init();
            },800)
        },
        // 触底触发
        reachBottom() {
            if (this.waterfall.renderEnd) {
                if (this.waterfall.status === 'nomore') return
                this.waterfall.status = 'loading'
                const nextPage = this.ajax.page + 1
                this.ajax.page = nextPage
                this.getData();
            }
        },
        init(){
            this.isLoaded = false;
            this.ajax = {
                load: true,
                page: 1,
                dataList: []
            }
            this.waterfall = {
                // 组件状态
                status: '',
                // 是否渲染完成
                renderEnd: true
            }
            this.zanId = [];
            this.getData();
        },
        // 获取数据
        async getData() {
            const { code, data } = await this.$api.get('index/dynamic', {
                page: this.ajax.page,
                type: 2,
            })
            if (code === 1) {
                if (!this.ajax.load) {
                    return;
                }
                this.ajax.load = false;
                data.data.forEach((v)=>{
                    if(v.is_likes){
                        v.likes = v.likes - 1;
                        this.zanId.push(v.dynamic_id)
                    }
                    v.imgUrl = v.medias[0];
                })
                const reset = this.ajax.page === 1 ? true : false;
                // 若是重绘列表的话,需要取消 `hideList`属性,隐藏状态下会引发列表尺寸获取错误的问题
                if (reset) {
                    this.waterfall.status = '';
                }
                if(this.ajax.page == 1 && data.data.length < 1){
                    this.waterfall.status = 'empty'
                }else if (data.last_page <= data.current_page) {
                    this.waterfall.status = 'nomore'
                } else {
                    this.waterfall.status = 'loadmore'
                }
                // 调用 render 方法,使组件开始进入渲染阶段
                this.ajax.dataList = this.ajax.dataList.concat(data.data);
                this.$refs.helangWaterfall.render(this.ajax.dataList, reset);
                this.ajax.load = true;
            }
            
        },
        // 监听渲染高度,此事件为必用
        onRenderHeight(e) {
            const { colIndex, height } = e;
            // 上报当前高度,上报后会自动触发下一项数据的渲染
            this.$refs.helangWaterfall.reportHeight(colIndex, height);
        },
        // 导航状态切换演示监听
        onStatusChange() {
            const vlaues = ['', 'fail', 'empty'];
            const labels = ['正常展示', '加载异常', '无结果'];
            uni.showActionSheet({
                itemList: labels,
                success: (res) => {
                    this.waterfall.status = vlaues[res.tapIndex];
                }
            });
        },
        // 详情
        handleToDetail(item) {
            if (item.type === 2) {
                this.$push('/subpages/home/dynamic-video?dynamic_id=' + item.dynamic_id)
            } else {
                this.$push('/subpages/home/dynamic-detail?dynamic_id=' + item.dynamic_id)
            }
        },
        // 点赞
        async handleLike(item) {
            const { code } = await this.$api.post('/index/likes', { target_id: item.dynamic_id, target: 1 })
            if (code === 1) {
                item.is_likes = !item.is_likes
                if (item.is_likes) {
                    item.likes++
                } else {
                    item.likes--
                }
                this.$nextTick(()=>{
                    if(this.zanId.includes(item.dynamic_id)){
                        let idx = this.zanId.findIndex((v)=>{
                            return v == item.dynamic_id
                        })
                        this.zanId.splice(idx,1)
                    }else{
                        this.zanId.push(item.dynamic_id)
                    }
                })
               
            }

        },
        // 处理瀑布流渲染状态
        handleStatusChange(status) {
            if (status === 'RENDER_END') {
                this.waterfall.renderEnd = true;
            } else {
                this.waterfall.renderEnd = false;
            }
        }
    }
}
</script>

<style lang="scss">
page {
    background-color: #f3f3f3;
}

.content {
    padding: 20rpx;
    background-color: white;
    border-radius: 4px;
    line-height: 1.3;

    .image {
        display: block;
        width: 100%;
        height: auto;
    }

    .ellipsis-1 {
        white-space: nowrap; // 强制一行显示
        overflow: hidden; // 超出隐藏
        text-overflow: ellipsis; // 省略号
    }

    .title {
        font-size: 28rpx;
        color: #666;
        margin: 20rpx 0;
    }

    .shop {
        font-size: 24rpx;
        color: #666;
        margin-top: 20rpx;
    }

    .label {
        padding: 10rpx 20rpx;
        border-radius: 100px;
        background-color: #F00;
        color: white;
        font-size: 24rpx;
        display: inline-block;
        line-height: 1;
    }

    .money {
        font-size: 28rpx;
        color: #F00;
        margin-top: 10rpx;
    }
}

.load-txt {
    padding: 0;
    text-align: center;
    color: #999;
    font-size: 24rpx;
}

.load-icon {
    width: 300rpx;
    height: 300rpx;
    margin: 0 auto 20rpx auto;
    display: block;
}
.personal-title {
    font-size: 26rpx;
    color: #000;
    font-weight: 700;
    margin-top: 6rpx;
}
.personal-fun {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 14rpx;
}

.personal-user {
    display: flex;
    align-items: center;
    font-size: 20rpx;
    color: #666666;
    font-weight: 500;

    image {
        width: 32rpx;
        height: 32rpx;
        border-radius: 50%;
        margin-right: 8rpx;
    }
}

.personal-r {
    display: flex;
    align-items: center;
    font-size: 24rpx;
    color: #666666;
    .personal-likes{
        margin-top: 4rpx;
    }

    .iconfont {
        width: 32rpx;
        height: 32rpx;
        margin-right: 8rpx;
    }
    .yes{
        color: #ff5000;
    }
}
</style>

问题:嵌套层级导致点赞不改变源数据

思路:通过数组的方式。初始的时候,数量-1,将点赞id存储起来,通过方法的方式将其调用,

优化:通过对象应该是会更加方便的。但是对象不知道为什么值没有改变,暂时也不细究了。先实现再说了。

点赞方法

实现效果


原文地址:https://blog.csdn.net/weixin_45638909/article/details/144368308

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!