前端实践-手机购物车效果 | 豆包MarsCode AI 刷题

36 阅读3分钟

我们在开发移动端购物相关的应用时,购物车功能是一个核心组成部分。本文将详细描述如何使用 JavaScript 创建一个简洁而实用的外卖购物车效果。

以下是整个过程的关键步骤,带你一步步实现一个基础的购物车功能。

1. 规划数据结构

在实现购物车之前,我们需要设计并定义一套数据结构。

假设我们有多个商品,每个商品包含了图片、标题、描述、月售数量、好评率以及价格等信息。

const products = [
  {
    image: './assets/product1.png',
    title: '椰云拿铁',
    description: '美味的椰浆拿铁,口感滑顺。',
    price: 32.0,
    sold: 200,
    rating: 95,
  },
  {
    image: './assets/product2.png',
    title: '生椰拿铁',
    description: '香醇浓郁的生椰拿铁。',
    price: 19.9,
    sold: 1000,
    rating: 100,
  },
  {
    image: './assets/product3.png',
    title: '加浓美式',
    description: '浓烈的美式咖啡,提神醒脑。',
    price: 20.3,
    sold: 200,
    rating: 93,
  },
];

接下来,我们将创建一个购物车类来管理商品选择的数量。

2. 创建商品和购物车类

我们将商品封装成一个类 Product,购物车的逻辑封装在 Cart 类中,Cart 负责管理商品数量的增减以及总价计算。

class Product {
  constructor(data) {
    this.data = data;
    this.quantity = 0;  // 商品选择数量
  }

  // 增加商品数量
  increase() {
    this.quantity++;
  }

  // 减少商品数量
  decrease() {
    if (this.quantity > 0) {
      this.quantity--;
    }
  }

  // 获取当前商品的总价格
  getTotalPrice() {
    return this.quantity * this.data.price;
  }

  // 判断商品是否被选中
  isSelected() {
    return this.quantity > 0;
  }
}

class Cart {
  constructor(products) {
    this.products = products.map(item => new Product(item));
    this.deliveryThreshold = 30;  // 起送金额
    this.deliveryFee = 5;         // 配送费
  }

  // 获取总价
  getTotalPrice() {
    return this.products.reduce((total, product) => total + product.getTotalPrice(), 0);
  }

  // 获取选中的商品数量
  getTotalQuantity() {
    return this.products.reduce((total, product) => total + product.quantity, 0);
  }

  // 是否跨过起送标准
  isDeliveryThresholdMet() {
    return this.getTotalPrice() >= this.deliveryThreshold;
  }

  // 获取配送费
  getDeliveryFee() {
    return this.isDeliveryThresholdMet() ? 0 : this.deliveryFee;
  }

  // 计算总价(包括配送费)
  getFinalPrice() {
    return this.getTotalPrice() + this.getDeliveryFee();
  }

  // 增加商品数量
  increaseProductQuantity(index) {
    this.products[index].increase();
  }

  // 减少商品数量
  decreaseProductQuantity(index) {
    this.products[index].decrease();
  }
}

3. 创建页面结构和UI更新

接下来,我们需要创建一个简单的页面结构,显示商品列表以及购物车信息。在用户选择商品时,更新购物车的内容。

<div class="menu">
  <div class="menu-item">推荐</div>
  <div class="menu-item">热销</div>
  <div class="menu-item">折扣</div>
  <!-- 更多菜单项 -->
</div>

<div class="products-list">
  <!-- 商品列表将动态生成 -->
</div>

<div class="footer">
  <div class="footer-info">
    <span class="total-price">总价:¥0.00</span>
    <span class="delivery-fee">配送费:¥5.00</span>
  </div>
  <div class="checkout">
    <button>去结算</button>
  </div>
</div>

CSS 简单样式:

.products-list {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.product-item {
  width: 200px;
  padding: 10px;
  border: 1px solid #ddd;
}

.footer {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  background-color: #f9f9f9;
}

.checkout button {
  background-color: #ff7200;
  color: white;
  border: none;
  padding: 10px 20px;
  cursor: pointer;
}

.checkout button:hover {
  background-color: #ff5a00;
}

4. 实现动态渲染和事件绑定

现在,我们需要将商品列表渲染到页面上,并为每个商品添加加减按钮。

通过监听按钮点击事件,更新购物车的数据并动态更新UI。

class UI {
  constructor(cart) {
    this.cart = cart;
    this.doms = {
      productsList: document.querySelector('.products-list'),
      totalPrice: document.querySelector('.total-price'),
      deliveryFee: document.querySelector('.delivery-fee'),
    };
    this.renderProducts();
    this.updateFooter();
    this.listenEvents();
  }

  // 渲染商品列表
  renderProducts() {
    const html = this.cart.products.map((product, index) => `
      <div class="product-item">
        <img src="${product.data.image}" alt="${product.data.title}">
        <h3>${product.data.title}</h3>
        <p>${product.data.description}</p>
        <p>价格:¥${product.data.price}</p>
        <div class="quantity-control">
          <button class="decrease" data-index="${index}">-</button>
          <span>${product.quantity}</span>
          <button class="increase" data-index="${index}">+</button>
        </div>
      </div>
    `).join('');
    this.doms.productsList.innerHTML = html;
  }

  // 更新底部购物车信息
  updateFooter() {
    const totalPrice = this.cart.getFinalPrice();
    this.doms.totalPrice.textContent = `总价:¥${totalPrice.toFixed(2)}`;
    this.doms.deliveryFee.textContent = `配送费:¥${this.cart.getDeliveryFee()}`;
  }

  // 监听按钮点击事件
  listenEvents() {
    this.doms.productsList.addEventListener('click', (e) => {
      const index = e.target.dataset.index;
      if (e.target.classList.contains('increase')) {
        this.cart.increaseProductQuantity(index);
      } else if (e.target.classList.contains('decrease')) {
        this.cart.decreaseProductQuantity(index);
      }
      this.renderProducts();
      this.updateFooter();
    });
  }
}

// 初始化购物车和UI
const cart = new Cart(products);
const ui = new UI(cart);

5. 总结

这只是一个简单的外卖购物车实现。通过面向对象的方式,我们将商品和购物车封装成独立的类,方便管理。UI 的更新通过监听事件和更新DOM来实现。

通过本文的流程,你应该能够掌握外卖购物车的基本实现方法。通过合理设计数据结构、封装类、动态渲染页面,我们能够快速地构建出符合需求的购物车功能。