本文介绍: 是一个强大的商品列表组件支持瀑布布局,非常适合用于展示大量商品。

ccproductwaterfall仿天猫淘宝购物车店铺商品列表组件

引言

电商应用中,购物车体验优化对于提升用户满意度转化率至关重要。在本文中,我们将深入探讨如何使用ccproductwaterfall组件结合uninumberboxxgwidget,来构建一个仿天猫淘宝购物车店铺商品列表。同时,我们将详细解析相关事件处理函数,以实现如商品过滤、店铺勾选、商品勾选、数量改变以及全选功能

组件介绍

ccproductwaterfall

cc-product-waterfall一个强大的商品列表组件,支持瀑布布局,非常适合用于展示大量商品。

uninumberbox

uni-number-box一个数字输入框组件,用户可以通过它方便地修改商品数量。

xgwidget

xg-widget一套通用的UI组件库,可以帮助我们快速构建出复杂交互性强的用户界面

购物车店铺商品列表实现

步骤1:引入必要的组件

首先,确保你的项目中已经引入ccproductwaterfalluninumberboxxgwidget等组件。具体的引入方法可能会根据你使用框架或库有所不同

步骤2:构建基本布局

使用ccproductwaterfall构建商品列表,uninumberbox用于商品数量的输入xgwidget中的checkbox组件用于实现店铺和商品的勾选功能

步骤3:添加交互功能

通过事件处理函数来实现各种交互功能,包括商品过滤、店铺勾选、商品勾选、数量改变以及全选等。

事件处理详解

过滤选择的商品和未选择的商品

filterCheckedProductfilterUncheckedProduct方法分别用于过滤出已选择和未选择的商品。这两个方法都接受一个商品列表作为参数然后使用数组filter方法根据商品的checked属性进行过滤

示例代码
使用方法

引入uni-number-box xg-widget组件

事件处理如下:
// 过滤选择的商品
filterCheckedProduct(products) {
return products.filter(item => item.checked);
},
// 过滤选择的商品
filterUncheckedProduct(products) {
return products.filter(item => !item.checked);
},
// 店铺勾选
onShopCheckboxTap(shop) {
shop.checked = !shop.checked;

shop.products.forEach(product => {
product.checked = shop.checked;
});
},
// 商品勾选
onProductCheckboxTap(product) {
product.checked = !product.checked
},
// 数量改变
onNumberBoxChange(product, e) {
product.count = e;
},
// 全选
onCheckAllTap() {
const checked = !this.allChecked;
this.shops.forEach(shop => {
shop.products.forEach(product => {
product.checked = checked;
})
})
}
HTML代码实现部分

<template>
    <view>
        <!-- 空购物车 -->
        <view v-if="isEmptyCart"
            class="bg-color-white border-bottom-left-radius-xl border-bottom-right-radius-xl padding-lg">
            <view class="row-center-center">
                <image class="img-size-xl" src="/static/cart/empty-cart.png" mode="aspectFit"></image>
                <text class="font-size-lg text-color-greyblack">购物车是空的</text>
            </view>
            <view class="row-center-center">
                <text class="empty-button">逛逛秒杀</text>
                <text class="empty-button">看看关注</text>
            </view>
        </view>

        <!-- 非空购物车 -->
        <view v-if="!isEmptyCart">
            <view v-for="(shop, shopIndex) of cartShops" :key="shopIndex"
                class="padding-lg margin-bottom-lg bg-color-white border-radius-xl">
                <!-- 店铺购物车商品 -->
                <!-- 店铺标题 -->
                <view class="" @tap="onShopCheckboxTap(shop)">
                    <label class="row-between-center">
                        <view class="row-center-center">
                            <checkbox class="shop-checkbox" :checked="shop.checked" />
                            <image class="img-size-base border-radius-circle" :src="shop.logo" mode="aspectFit"></image>
                            <text class="font-size-lg">{{shop.name}}</text>
                        </view>
                        <!-- <view class=""></view> -->
                    </label>
                </view>

                <!-- 店铺产品列表 -->
                <view class="row-between-start margin-top-base" v-for="(product, productIndex) of shop.products"
                    :key="productIndex">
                    <view class="product-checkbox" @tap="onProductCheckboxTap(product)">
                        <checkbox :checked="product.checked" />
                    </view>

                    <image class="border-radius-lg product-image" :src="product.image" mode=""></image>
                    <view class="flex-1 column-center-stretch padding-left-lg">
                        <text class="lines-2 font-size-base">{{product.title}}</text>
                        <view class="row-start-center margin-v-side-base">
                            <view
                                class="row-center-center bg-color-grey border-radius-rect-circle padding-side-base padding-v-side-xs">
                                <text v-for="(property, propertyIndex) of product.sku" :key="propertyIndex"
                                    class="font-size-sm">{{property}},</text>
                            </view>
                        </view>

                        <view class="row-between-center">
                            <xg-money camel :size="UNI_FONT_SIZE_XL" :money="product.price"></xg-money>

                            <view class="number-box">
                                <uni-number-box :min="1" :value="product.count"
                                    @change="onNumberBoxChange(product, $event)"></uni-number-box>
                            </view>
                        </view>
                    </view>
                </view>

            </view>
        </view>

        <view class="order-amount-placeholder"></view>
        <view class="row-between-center bg-color-white padding-side-lg order-amount">
            <view class="row-center-center">
                <view class="product-checkbox" @tap="onCheckAllTap">
                    <checkbox :checked="allChecked" />
                </view>
                <text class="font-size-base">全选</text>
                <text class="font-size-lg margin-left-lg">合计:</text>
                <text class="font-size-lg font-weight-bold">¥{{totalAmount.toFixed(2)}}</text>
            </view>

            <view class="bg-color-red border-radius-rect-circle padding-side-lg padding-v-side-base">
                <text class="font-size-lg text-color-white">去结算({{totalCount}})</text>
            </view>
        </view>
    </view>
</template>

<script>
    // 获取购物车数据来源
    import data from '@/data/cart/cart';

    import mixin from '@/common/mixin';

    const customData = {
        page: 0
    }

    export default {
        mixins: [mixin],
        data() {
            return {
                isEmptyCart: false,
                loadMoreStatus: 'more',

                shops: [],

            };
        },

        computed: {
            // 全选事件
            allChecked() {
                return this.cartShops.filter(item => item.checked).length === this.cartShops.length;
            },

            // 购物车店铺数据
            cartShops() {
                this.shops.forEach(shop => {
                    const uncheckedProducts = this.filterUncheckedProduct(shop.products);

                    shop.checked = (uncheckedProducts.length === 0);
                })

                return this.shops;
            },

            // 计算数totalCount() {
                let count = 0;

                this.cartShops.forEach(shop => {
                    this.filterCheckedProduct(shop.products).forEach(product => {
                        count += parseInt(product.count);
                    })
                })

                return count;
            },
            // 计算金额
            totalAmount() {
                let amount = 0;

                this.cartShops.forEach(shop => {
                    this.filterCheckedProduct(shop.products).forEach(product => {
                        amount += Number(product.price * product.count)
                    })
                })

                return amount;
            }
        },

        async created() {
            this.loadMoreStatus = 'loading';

            // 获取商铺数据
            const shopPromise = data.shops();

            this.shops = await shopPromise;

        },

        methods: {
            // 过滤选择的商品
            filterCheckedProduct(products) {
                return products.filter(item => item.checked);
            },
            // 过滤选择的商品
            filterUncheckedProduct(products) {
                return products.filter(item => !item.checked);
            },
            // 店铺勾选
            onShopCheckboxTap(shop) {
                shop.checked = !shop.checked;

                shop.products.forEach(product => {
                    product.checked = shop.checked;
                });
            },
            // 商品勾选
            onProductCheckboxTap(product) {
                product.checked = !product.checked
            },
            // 数量改变
            onNumberBoxChange(product, e) {
                product.count = e;
            },
            // 全选
            onCheckAllTap() {
                const checked = !this.allChecked;
                this.shops.forEach(shop => {
                    shop.products.forEach(product => {
                        product.checked = checked;
                    })
                })
            }

        },
    }
</script>

<style lang="scss" scoped>
    .empty-button {
        @include border(1px solid);

        font-size: $uni-font-size-lg;
        border-radius: $uni-border-radius-rect-circle;
        margin: 0 $uni-spacing-col-xl;
        padding: $uni-spacing-row-sm $uni-spacing-col-xl;
    }

    $order-amount-height: 100rpx;

    .product-list {
        /* #ifdef APP-NVUE */

        @include position(fixed, 0 0 $order-amount-height 0);
        /* #endif */

        // width: 500rpx;
    }

    .shop-checkbox {
        transform: scale(0.8);
    }

    .product-checkbox {
        transform: scale(0.75);
    }

    .product-image {
        width: 200rpx;
        height: 200rpx;
    }

    .number-box {
        transform-origin: 100% 50%;
        transform: scale(0.75);
    }

    .order-amount-placeholder {
        height: $order-amount-height;
    }

    .order-amount {
        /* #ifndef APP-NVUE */
        @include position(fixed, none 0 var(--window-bottom) 0);
        /* #endif */
        /* #ifdef APP-NVUE */
        @include position(fixed, none 0 0 0);
        /* #endif */

        height: $order-amount-height;

        /* #ifndef APP-NVUE */
        z-index: 10000;
        /* #endif */
    }
</style>

店铺勾选和商品勾选功能实现

用户点击店铺或商品的勾选框时,我们需要更新对应的checked状态onShopCheckboxTap方法用于处理店铺的勾选事件,它会更新店铺及其所有商品的checked状态onProductCheckboxTap方法用于处理商品的勾选事件,只会更新当前商品的checked状态。这两个方法都使用了JavaScript的逻辑操作符来实现checked状态切换。当用户点击全选按钮时,onCheckAllTap法将会被调用这个方法会检查当前的全选状态然后遍历所有的店铺和商品,将它们的checked状态设置为相反的值。这样就可以实现一键全选或全不选功能

 阅读全文下载完整组件代码关注微信公众号: 前端组件开发

d848d5658a07453c843277846948c608.png


原文地址:https://blog.csdn.net/chenchuang0128/article/details/134763517

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_32370.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注