Vue.js 购物车组件

应用场景

本代码是一个 Vue.js 组件,可用于创建购物车的交互式 UI。它允许用户查看和管理其购物篮中的商品,包括数量、价格和总价。该组件适用于电子商务网站或任何需要提供购物车功能的应用程序。

基本功能

  • **显示购物车中的商品列表:**组件显示购物车中所有商品的列表,包括商品名称、尺寸、颜色、数量和价格。
  • **更新商品数量:**用户可以增加或减少商品数量。
  • **计算总价:**组件根据商品数量和价格实时计算购物车的总价。
  • **提交订单:**用户可以单击一个按钮来提交订单。

功能实现步骤及关键代码分析

1. 组件模板

组件模板定义了购物车的外观和布局。它使用 v-for 指令循环遍历 products 数组,并为每个商品创建一个列表项。每个列表项包含以下元素:

  • 商品图像:img 元素显示商品图像。
  • 商品详细信息:h3 元素包含商品名称、尺寸和颜色。
  • 数量控制:button 元素允许用户增加或减少商品数量。
  • 价格:p 元素显示商品价格。
<template>
  <div class="bg-gray-100">
    <div class="max-w-7xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
      <div class="bg-white shadow sm:rounded-lg">
        <div class="px-4 py-5 sm:px-6">
          <h3 class="text-lg leading-6 font-medium text-gray-900">
            Shopping Cart
          </h3>
        </div>
        <div class="divide-y divide-gray-200">
          <div class="px-4 py-6 sm:px-6">
            <ul role="list" class="space-y-4">
              <!-- 循环遍历商品并创建列表项 -->
              <li v-for="product in products" :key="product.name" class="flex items-center py-6 sm:py-12">
                <!-- 商品图像 -->
                <div
                  class="flex-shrink-0 w-24 h-24 border border-gray-200 rounded-md overflow-hidden"
                >
                  <img
                    :src="product.image"
                    :alt="product.name"
                    class="w-full h-full object-center object-cover"
                  />
                </div>
                <!-- 商品详细信息 -->
                <div class="ml-4 flex-1 flex flex-col justify-between sm:ml-6">
                  <h3>
                    <div class="font-medium text-gray-900">{{ product.name }}</div>
                    <p class="mt-1 text-sm text-gray-500">{{ product.size }} {{ product.color }}</p>
                  </h3>
                  <!-- 数量控制 -->
                  <div class="flex items-center justify-between mt-4">
                    <div class="flex items-center">
                      <button
                        type="button"
                        class="inline-flex items-center text-gray-500 hover:text-gray-700"
                        @click="decrementQuantity(product)"
                      >
                        <svg
                          class="w-5 h-5"
                          xmlns="http://www.w3.org/2000/svg"
                          viewBox="0 0 20 20"
                          fill="currentColor"
                          aria-hidden="true"
                        >
                          <path
                            d="M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z"
                          />
                        </svg>
                      </button>
                      <span class="mx-3 text-sm font-medium text-gray-900">{{ product.quantity }}</span>
                      <button
                        type="button"
                        class="inline-flex items-center text-gray-500 hover:text-gray-700"
                        @click="incrementQuantity(product)"
                      >
                        <svg
                          class="w-5 h-5"
                          xmlns="http://www.w3.org/2000/svg"
                          viewBox="0 0 20 20"
                          fill="currentColor"
                          aria-hidden="true"
                        >
                          <path
                            d="M10.29 3.291A1 1 0 0111 3h2.71a1 1 0 01.707 1.707l3.323 3.323a1 1 0 010 1.414l-2.71 2.71a1 1 0 01-1.414 0L11 7.414V11h2.71a1 1 0 01.707 1.707l3.323 3.323a.999.999 0 010 1.414l-2.71 2.71a1 1 0 01-1.414 0L11 16.586V19h-2.71a1 1 0 01-.707-1.707L4.677 14.293a1 1 0 010-1.414l2.71-2.71a1 1 0 011.414 0L11 10.586h2.71a1 1 0 01.707 1.707l3.323 3.323a1 1 0 010 1.414l-2.71 2.71a1 1 0 01-1.414 0L11 18.586V21h-2.71a1 1 0 01-.707-1.707l-3.323-3.323a1 1 0 010-1.414l2.71-2.71a1 1 0 011.414 0l3.413 3.413z"
                          />
                        </svg>
                      </button>
                    </div>
                    <!-- 价格 -->
                    <p class="text-sm font-medium text-gray-900">{{ product.price | currency }}</p>
                  </div>
                </div>
              </li>
            </ul>
          </div>
          <!-- 总价 -->
          <div
            class="px-4 py-6 flex justify-between text-base font-medium text-gray-900 border-t border-gray-200 sm:px-6"
          >
            <p>Total price</p>
            <p>{{ total | currency }}</p>
          </div>
          <!-- 提交订单按钮 -->
          <div class="px-4 py-6 sm:px-6">
            <button
              type="button"
              class="inline-flex items-center justify-center w-full px-4 py-2 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
            >
              Place Order
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

2. 组件逻辑

组件逻辑使用 Vue.js 的 script 标签实现。它定义了以下功能:

  • **products 数据:**一个响应式数组,存储购物车中的商品。
  • **total 计算属性:**计算购物车中的总价。
  • **incrementQuantitydecrementQuantity 方法:**用于增加或减少商品数量。
<script lang="tsx" setup>
import { ref } from 'vue';

const products = ref([
  {
    name: 'Air Bender',
    size: 'M',
    color: 'Black',
Login
ECHO recommendation
ScriptEcho.ai

User Annotations

我的设计稿名字是:我的购物车 我的设计稿的页面功能是:用户在该页面可以对商品进行增删改查等操作,并最终提交订单。