业务功能·

实现购物车的通用方案

本文将使用两个类 UIGoods 和 UIData 来分别管理单个商品和整个商品列表的状态和操作,并结合 Vue.js 框架实现一个简单应用案例。

1. UIGoods 类

UIGoods 类用于管理单个商品的状态和操作。它包含以下方法和属性:

  • constructor(g): 构造函数,接受一个商品对象 g 并初始化商品数据和选中数量。
  • getGoodsPrice(): 计算当前选中商品的总价。
  • addGoods(): 增加当前商品的选中数量。
  • reduceGoods(): 减少当前商品的选中数量(如果选中数量大于0)。
  • isChoose(): 判断当前商品是否被选中。

2. UIData 类

UIData 类用于管理整个商品列表的状态和操作。它包含以下方法和属性:

  • constructor(goods, expressFee, minDeliveryPrice): 构造函数,接受商品列表、配送费和最低配送价格,并初始化商品列表。
  • getGoodsPrice(): 计算所有选中商品的总价。
  • getGoodsCount(): 获取所有选中商品的总数量。
  • addGoods(index): 根据商品索引增加商品的选中数量。
  • reduceGoods(index): 根据商品索引减少商品的选中数量。
  • hasGoods(): 判断购物车中是否有商品。
  • isDelivery(): 判断是否满足最低配送价格。
  • handleExpressFee(): 根据商品总价处理不同的配送费用。

完整代码

class UIGoods {
  constructor(g) {
    this.data = g;
    this.choose = 0;
  }
  // 计算价格
  getGoodsPrice() {
    return this.data.price * this.choose;
  }
  // 新增当前商品数量
  addGoods() {
    this.choose += 1;
  }
  // 减少当前商品数量
  reduceGoods() {
    if (this.choose === 0) {
      return;
    }
    this.choose -= 1;
  }
  // 是否选中了此商品
  isChoose() {
    return this.choose > 0;
  }
}

class UIData {
  constructor(goods, expressFee, minDeliveryPrice) {
    this.uiGoods = goods.map((good) => new UIGoods(good));
    // 配送费
    this.expressFee = expressFee;
    // 最少配送价格
    this.minDeliveryPrice = minDeliveryPrice;
  }
  // 获取所有商品的总价
  getGoodsPrice() {
    return this.uiGoods.reduce((acc, cur) => acc + cur.getGoodsPrice(), 0);
  }
  // 获取所有商品数量
  getGoodsCount() {
    return this.uiGoods.reduce((acc, cur) => acc + cur.choose, 0);
  }
  // 根据商品索引新增商品选中数量
  addGoods(index) {
    this.uiGoods[index].addGoods();
  }
  // 根据商品索引减少商品选中数量
  reduceGoods(index) {
    this.uiGoods[index].reduceGoods();
  }
  // 购物车有没有商品
  hasGoods() {
    return this.getGoodsCount() > 0;
  }
  // 是否满足配送价格
  isDelivery() {
    return this.getGoodsPrice() >= this.minDeliveryPrice;
  }
  // 根据商品总价处理不同快递费
  handleExpressFee() {
    if (this.getGoodsPrice() >= 100) {
      return 0;
    } else if (this.getGoodsPrice() >= 50) {
      return 10;
    } else {
      return this.expressFee;
    }
  }
}

var goods = [
  {
    id: 1,
    price: 10,
    name: "苹果",
  },
];
var ug = new UIData(goods, 5, 20);

Vue 使用示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue.js 商品管理示例</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="./index.js"></script>
</head>

<body>
    <div id="app">
        <h1>商品列表</h1>
        <ul>
            <li v-for="(good, index) in uiData.uiGoods" :key="good.data.id">
                {{ good.data.name }} - ¥{{ good.data.price }}
                <button @click="addGoods(index)">+</button>
                <span>{{ good.choose }}</span>
                <button @click="reduceGoods(index)">-</button>
            </li>
        </ul>
        <h2>购物车信息</h2>
        <p>总价: ¥{{ uiData.getGoodsPrice() }}</p>
        <p>配送费: ¥{{ uiData.handleExpressFee() }}</p>
        <p>总数量: {{ uiData.getGoodsCount() }}</p>
        <p v-if="uiData.isDelivery()">满足最低配送价格</p>
        <p v-else>不满足最低配送价格</p>
    </div>

    <script>
        const { createApp, reactive } = Vue
        createApp({
            setup() {
                const uiData = reactive(new UIData(
                    [
                        { id: 1, price: 10, name: "苹果" },
                        { id: 2, price: 20, name: "香蕉" },
                        { id: 3, price: 30, name: "橙子" },
                    ],
                    5,
                    20
                ))
                return {
                    uiData,
                    addGoods(index) {
                        this.uiData.addGoods(index);
                    },
                    reduceGoods(index) {
                        this.uiData.reduceGoods(index);
                    }
                }
            }
        }).mount('#app')
    </script>
</body>

</html>