【前端小程序】06 - 购物车页面

1. 添加收货地址按钮

1.1 页面结构与样式

  1. 页面结构:

    
   
        
   

  1. 页面样式:
.cart {

    .address_btn {
        padding: 20rpx;
        button {
            color: var(--themeColor); 
            width: 60%;
        }
    }
}

1.2 处理添加收货地址事件

    /**
     * 处理添加收获地址事件
     */
    addAddressHandle() {
        wx.chooseAddress({
            success: (result) => {
                console.log(result);
            },
        });
    },
  1. 点击添加收货地址按钮时如果我们没有点击确定,而是点击取消。这时会出现问题:之后再次点击添加收货地址按钮的时候就打不开选择地址的界面了。

1.3 权限演示

  1. 用户获取对小程序所授予获取地址的权限状态scope

假设用户点击 获取地址的提示框的确定按钮 authSetting{scope.address 的值是 true}
假设用户点击获取地址的提示框的取消按钮 scope 的值是 false
假设用户没有调用过选择地址的api scope 的值是 undefined

  1. 查看权限信息:wx.getSetting
wx.getSetting({
            success: (result) => {
                console.log(result);
            },
        });
  1. 解决点击了获取选择地址对话框取消按钮后无法再调起的问题:
addAddressHandle() {
        // 正确获取收货地址的流程
        wx.getSetting({
            success: (result) => {
                // 遇到这种比较特殊的属性名称的时候需要使用 [] 进行获取
                const scopeAddress = result.authSetting["scope.address"]
                if (scopeAddress === true || scopeAddress === undefined) {
                    // 表示曾经用户授予于了获取地址的权限 可以直接调用选择收货地址
                    wx.chooseAddress({
                        success: (result1) => {
                            console.log(result1);
                        }
                    });
                } else {
                    // 曾经用户取消了选择收货地址权限的获取 需要重新让用户为选择收货地址授权
                    wx.openSetting({
                        success: (result2) => {
                            console.log(result2);
                            // 重新选择收货地址
                            wx.chooseAddress({
                                success: (result3) => {
                                    console.log(result3);
                                }
                            });
                        }
                    });
                }
            },
        });
    },
  1. 使用ES7的语法优化以上的操作:
/**
 * 权限设置
 */
export const getSetting = () => {
    return new Promise((resolve, reject) => {
        wx.getSetting({
            success: (result) => {
                resolve(result);
            },
            fail: (error) => {
                reject(error);
            }
        });
    });
}

export const chooseAddress = () => {
    return new Promise((resolve, reject) => {
        wx.chooseAddress({
            success: (result) => {
                resolve(result);
            },
            fail: (error) => {
                reject(error);
            }
        });
    });
}

export const openSetting = () => {
    return new Promise((resolve, reject) => {
        wx.openSetting({
            success: (result) => {
                resolve(result);
            },
            fail: (error) => {
                reject(error);
            }
        });
    });
}
 async addAddressHandle() {
        // 正确获取收货地址的流程

        // 使用ES7优化后的代码
        try {
            const setRes = await getSetting();
            const scopeAddress = setRes.authSetting["scope.address"]
            console.log(scopeAddress);
            // 判断当前权限状态
            if (scopeAddress === false) {
                await openSetting();
            }
            // 调用获取收货地址的 api
            const address = await chooseAddress();
            // 将获取结果存入到缓存中
            wx.setStorageSync("address", address);
        } catch (err) {
            console.log(err);
        }
    },

1.4 获取本地存储中的地址数据

  1. 编写页面结构 :

    
    
   
        
   

   

  1. 编写页面样式:
 .user_info_row {
        display: flex;
        padding: 20rpx;     
        .user_info {
            flex:5;
        }

        .user_phone {
            flex:3;
            text-align: right;
        }
    }
  1. 首先在data中定义一个变量保存在缓存中获取到的地址信息,需要在onShow生命周期函数中进行获取设置数据。
/**
     * 生命周期函数--监听页面显示
     */
    onShow: function() {
        const address = wx.getStorageSync("address");
        this.setData({
            address
        });
    },

2.将缓存中的购物车商品数据显示到页面上

  1. 回到了商品详情页面,第一次添加商品的时候手动添加了属性

num = 1 ;
checked = true;

设置购物车复选框为选中状态
  1. onShow中获取缓存中的购物车数组。
  const cart = wx.getStorageSync("cart");
  1. 将购物车数据填充到data变量中。

3. 底部工具栏的功能

3.1 全选功能

  1. onshow中获取缓存中的购物车数组。

  2. 根据购物车中的商品数量,所有的商品都被选中 checked=true 全部就被选中。

  3. 数组的 every()方法的使用 : 会遍历会接受一个回调函数,那么每一个回调函数都会返回true,那么every()方法的返回值为true只要有一个回调函数返回false那么久不再循环执行,直接返回false。假如是一个空数组调用了every()方法返回值就是true

        // 获取缓存中的购物车数据
        const cart = wx.getStorageSync("cart");
        // 使用every函数遍历数组中的 checked 属性
        const allChecked = cart.length ? cart.every(v => v.checked) : false;
全选功能

3.2 计算总价格和总数量

  1. 都需要商品被选中我们才能拿来计算。

  2. 获取购物车数组。

  3. 遍历。

  4. 判断商品是否被选中。

  5. 总价格 += 商品单价 * 商品数量。

  6. 总数量 += 商品数量。

  7. 将计算后的价格和数量设置回data中。

计算总价格和总数量

3.3 复选框的选中与取消选中

  1. 绑定change 事件,并传递当前的商品id
   
  1. 获取到被修改的商品对象。

  2. 商品对象的选中状态取反。

        // 1. 接收传递过来的 商品 id
        const goods_id = e.currentTarget.dataset.id;
        // 2. 获取缓存中的购物车数据 
        const { cart } = this.data; // 在data中解构出 cart
        // 3. 查询该商品id对应的索引 
        const index = cart.findIndex(v => v.goods_id === goods_id);
        // 4 根据索引修改该商品的选中状态 
        cart[index].checked = !cart[index].checked;
  1. 重新填充回data中和缓存中。

  2. 重新计算全选。总价格 总数量。

  3. 将选中和取消选中、计算合计价格、合计数量 设置购物车到data和缓存中抽取为一个方法:

/**
     * 
     * @param {抽取处理 合计价格 合计数量设置购物车到data和缓存中的操作} cart 
     */
    setCart(cart) {
        // 使用every函数遍历数组中的 checked 属性
        // const allChecked = cart.length ? cart.every(v => v.checked) : false;
        let allChecked = true; // 事先将其设置为true 到后面循环的时候发现有false的时候再将其设置为 false
        let totalNum = 0;
        let totalPrice = 0;
        cart.forEach(v => {
            if (v.checked) {
                totalNum += v.num;
                totalPrice += v.goods_price * v.num;
            } else {
                allChecked = false;
            }
        });

        // 再对其值进行把关 
        allChecked = cart.length != 0 ? allChecked : false;
        this.setData({
            cart,
            allChecked,
            totalNum,
            totalPrice
        });
        // 重新将cart对象设置到缓存中 
        wx.setStorageSync("cart", cart);
    },

3.4 反选

  1. 复选框绑定一个change事件。

  2. 获取data中的选中状态 allchecked;

  3. 直接取反 allchecked = !allchecked;

  4. 遍历购物车数组让里面商品选中状态跟随allchecked改变而改变。

  5. 将购物车数组 和 allchecked重新设置会data中 和 缓存中。

3.5 商品数量的编辑功能

  1. "+" "-" 按钮绑定同一个点击事件区分的关键 自定义属性。

    "+" "+1"
    "-" "-1"


-
+
  1. 传递被点击的商品 id opt操作参数。

  2. 获取data中的购物车数组,来获取需要被修改的对象。

  3. 直接修改商品对象的数量num

  4. cart数组 重新设置会缓存中和data中 。

    /**
     * 
     * @param {购物车视频编辑事件} e 
     */
    editGoodsNum(e) {
        // 获取传递过来的商品id 和 按钮操作参数
        let { id, opt } = e.currentTarget.dataset;
        // 根据商品id在 cart数组中查找 对应的商品索引
        let { cart } = this.data;
        const index = cart.findIndex(v => v.goods_id === id);
        // 根据index修改数组中的指定商品信息 
        cart[index].num += opt;
        // 将修改后的购物车数组重新设置到缓存中和data中
        this.setCart(cart);
    },

3.6 删除商品

  1. 当购物车的数量某个商品数量为 1 的同时用户点击 "-" ,弹窗提示(showModel)询问用户是否需要删除。

  2. 将弹窗的请求的组件封装到,promise中通过ES7的去Promise简化操作。

/**
 * 简化模态框提示操作
 */
export const showModal = ({ content }) => {
    return new Promise((resolve, reject) => {
        wx.showModal({
            title: '提示',
            content: content,
            /* 这里需要使用箭头函数的形式 */
            success: (res) => {
                resolve(res);
            },
            fail: (err) => {
                reject(err);
            }
        });
    })
}
  1. 编辑购物车商品代码:

    /**
     * 
     * @param {购物车商品编辑事件} e 
     */
    async editGoodsNum(e) {
        // 获取传递过来的商品id 和 按钮操作参数
        let { id, opt } = e.currentTarget.dataset;
        // 根据商品id在 cart数组中查找 对应的商品索引
        let { cart } = this.data;
        const index = cart.findIndex(v => v.goods_id === id);

        /**
         * 如果当前商品的数量是 1 且用户的操作是进行减 1 操作 
         */
        if (cart[index].num === 1 && opt === -1) {
            const res = await showModal({ content: "您确定要删除当前商品吗?" });
            // 点击确定的时候
            if (res.comfirm) {
                cart.splice(index, 1);
                this.setCart(cart);
            }
        } else {
            // 根据index修改数组中的指定商品信息 
            cart[index].num += opt;
            this.setCart(cart);
        }
        // 将修改后的购物车数组重新设置到缓存中和data中
        this.setCart(cart);
    },

3.7 结算按钮功能

  1. 判断有没有收货地址信息。

  2. 判断用户有没有选购商品。

  3. 经过以上验证即可跳转到支付页面进行支付。

   /**
     * 处理结算逻辑
     */
    async handlePay() {
        const { address, totalNum } = this.data;

        if (!address.userName) {
            await showToast({ title: "您还未填写自己的地址信息!" });
            return;
        }

        if (totalNum == 0) {
            await showToast({ title: "您还未选择商品!" });
            return;
        }

        wx.navigateTo({
            url: '/pages/pay/index'
        });
    },
  1. 其中的 showToast 进行了抽取,使用ES7的Promise操作简化了操作:

/**
 * 简化页面提示
 */
export const showToast = ({ title }) => {
    return new Promise((resolve, reject) => {
        wx.showToast({
            title: title,
            icon: 'none',
            mask: true,
            success: (res) => {
                resolve(res)
            },
            fail: (err) => {
                reject(err);
            }
        });
    })
}

你可能感兴趣的:(【前端小程序】06 - 购物车页面)