React Native开发之双层购物车的简单设计与实现

最近从事React Native开发,有需求是做购物车界面。在网上查询了一番,大多都是单层的购物车,即局部单选和多选。但是主流的购物车界面都是有店铺单选、多选及商品的单选和多选的,所以用自己所学知识自己写了一个双层的购物车。
学习阶段,如果哪部分有问题,欢迎指正,共同探讨。@Apach3


我设计的时候是这样想的:
1. 页面分为三部分:导航栏、商品栏、价格栏;
2. 商品栏用FlatList实现,每个店铺都是对应的row;
3. 将不同商品push进数组里,然后返回给每个row;
4. 在最底层页面拿到数据,对数据处理,根据店铺分类,再将不同的店铺及商品追加对象字段select: true/false;

handleData = (array) => {//处理数据格式
        let nameArray = []; //  店名数组
        array.map(
            (item) => {
                nameArray.push(item.storeName);
            }
        );
        let storeNameArray = Array.from(new Set(nameArray));
        this.shopObjArray = [];
        storeNameArray.map(
            (item) => {
                this.shopObjArray.push({storeName: item, data: [], select: false});
            }
        );
        array.map(
            (item) => {
                for (let i = 0; i < this.shopObjArray.length; i++) {
                    if (this.shopObjArray[i].storeName == item.storeName) {
                        this.shopObjArray[i].data.push({data: item, select: false, number: 1});
                    }
                }
            }
        );
        this.loading = false;
        this.refs.buylist.judgeLoading(this.loading);
        this.refs.buylist.freshData(this.shopObjArray);
    }

5. 每个组件内容的值,均由最底层页面通过ref调用该类方法,传值过去刷新相应区域;
6. 点击全选后,回调去更新数据源对应的state,再将相应改变的部分新数据源传给对应组件,通过ref调用方法刷新组件;

changeHeaderData = (index) => {//点击店铺头部全选对应数据操作
        let newStatus = !this.shopObjArray[index].select
        this.shopObjArray[index].select = newStatus;
        this.shopObjArray[index].data.map(
            (item, index) => {
                item.select = newStatus;
            }
        );
        this.refs.buylist.reRenderStore(this.shopObjArray[index], index);
        this.judgeStoreCheck();
    }

7. 点击单选后,回调去更新数据源对应state,同时判断是否该店铺下商品全部已被单选,如果全被单选则更新店铺全选按钮,反之不更新;

changeStoreGoodsCheck = (storeIndex, index) => {//改变商铺对应下商品的选择状态
        let newStatus = !this.shopObjArray[storeIndex].data[index].select;
        this.shopObjArray[storeIndex].data[index].select = newStatus;
        this.refs.buylist.reRenderGoods(this.shopObjArray[storeIndex].data, storeIndex, index);
        let newArray = this.shopObjArray[storeIndex].data;
        let status = newArray[0].select;
        let contrastTimes = 0;
        for (let i = 0; i < newArray.length - 1; i++) {
            if (newArray[i].select == newArray[i + 1].select) {
                contrastTimes++;
            }
            else {
                break;
            }
        }
        if (contrastTimes == newArray.length - 1) {
            if (status == true) {
                this.shopObjArray[storeIndex].select = true;
            }
            else {
                this.shopObjArray[storeIndex].select = false;
            }
            this.refs.buylist.reRenderStore(this.shopObjArray[storeIndex], storeIndex);
        }
        else {
            this.shopObjArray[storeIndex].select = false;
            this.refs.buylist.reRenderStore(this.shopObjArray[storeIndex], storeIndex);
        }
        this.judgeStoreCheck();
    }

8. 底部总全选的实现方式类似,只是在局部单选的时候,同时需要判断所有店铺是否都被动全选而改变底部状态。

changePayCheck = (status) => {//底部总全选数据处理
        this.paySelect = status;
        this.refs.pricepay.reRenderPricePay(this.paySelect);
        this.shopObjArray.map(
            (item, index) => {
                this.shopObjArray[index].select = this.paySelect;
                this.shopObjArray[index].data.map(
                    (item, index) => {
                        item.select = this.paySelect;
                    }
                );
                this.refs.buylist.reRenderStore(this.shopObjArray[index], index);
            }
        );
        this.calculatePrice();
    }

judgeStoreCheck = () => {//判断更新店铺选择状态
        let newArray = this.shopObjArray;
        let status = newArray[0].select;
        let contrastTimes = 0;
        for (let i = 0; i < newArray.length - 1; i++) {
            if (newArray[i].select == newArray[i + 1].select) {
                contrastTimes++;
            }
            else {
                break;
            }
        }
        if (contrastTimes == newArray.length - 1) {
            if (status == true) {
                this.paySelect = true;
            }
            else {
                this.paySelect = false;
            }
        }
        else {
            this.paySelect = false;
        }
        this.refs.pricepay.reRenderPricePay(this.paySelect);
        this.calculatePrice();
    }
calculatePrice = () => {//计算价格
        this.totalPrice = 0;
        this.shopObjArray.map(
            (item, index) => {
                item.data.map(
                    (innerItem, innerIndex) => {
                        if (innerItem.select == true) {
                            this.totalPrice = innerItem.data.goodsPrices * innerItem.number + this.totalPrice;
                        }
                    }
                );
            }
        );
        this.refs.pricepay.changePrice(this.totalPrice);
    }

简易效果:
效果图1
效果图2
效果图3


项目github地址:ShoppingCartDemo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值