Browse Source

✨ feat(home): 实现商品列表

陈雪 1 month ago
parent
commit
2ab5349a29

+ 92 - 0
src/components/product-list/data.json

@@ -0,0 +1,92 @@
+[
+  {
+    "id": 1,
+    "name": "Wireless Bluetooth Earphones",
+    "price": 299.9,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Electronics",
+    "rate": 4.5,
+    "sold": 1200
+  },
+  {
+    "id": 2,
+    "name": "Smart Temperature-Control Cup",
+    "price": 159.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Daily Essentials",
+    "rate": 4.2,
+    "sold": 850
+  },
+  {
+    "id": 3,
+    "name": "Automatic Coffee Maker",
+    "price": 899.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Kitchen Appliances",
+    "rate": 4.8,
+    "sold": 430
+  },
+  {
+    "id": 4,
+    "name": "Portable Projector",
+    "price": 1299.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Audio-Visual Equipment",
+    "rate": 4.6,
+    "sold": 670
+  },
+  {
+    "id": 5,
+    "name": "Fitness Heart Rate Band",
+    "price": 199.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Sports & Health",
+    "rate": 4.0,
+    "sold": 2300
+  },
+  {
+    "id": 6,
+    "name": "Multi-Function Cooking Pot",
+    "price": 599.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Kitchen Appliances",
+    "rate": 4.7,
+    "sold": 980
+  },
+  {
+    "id": 7,
+    "name": "Noise-Canceling Sleep Earbuds",
+    "price": 89.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Daily Essentials",
+    "rate": 4.3,
+    "sold": 4500
+  },
+  {
+    "id": 8,
+    "name": "Gaming Mechanical Keyboard",
+    "price": 499.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Computer Peripherals",
+    "rate": 4.9,
+    "sold": 2100
+  },
+  {
+    "id": 9,
+    "name": "Smart Body Fat Scale",
+    "price": 199.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Sports & Health",
+    "rate": 4.1,
+    "sold": 3200
+  },
+  {
+    "id": 10,
+    "name": "Mini Blender",
+    "price": 399.0,
+    "cover": "https://t.xiaoyaotravel.com/image/TourImComplait/messageContent/890ed9e754c54ceaa886a3946d55adbe.png",
+    "category": "Kitchen Appliances",
+    "rate": 4.4,
+    "sold": 1500
+  }
+]

+ 102 - 0
src/components/product-list/product-item.vue

@@ -0,0 +1,102 @@
+<template>
+  <view class="product-item-container">
+    <view class="is-collect"></view>
+    <image :src="product.cover" class="w-328rpx" mode="widthFix"></image>
+    <view class="product-name">{{ product.name }}</view>
+    <view class="sell-rate">
+      <view class="rate">
+        {{ product.rate }}
+        <image src="@/static/images/rate.svg" class="w-28rpx ml-8rpx" mode="widthFix"></image>
+      </view>
+      <view class="sold">{{ product.sold }} Sold</view>
+    </view>
+    <view class="price-cart">
+      <view class="price">USD {{ product.price }}</view>
+      <view class="cart">
+        <image src="@/static/images/cart.svg" class="w-32rpx" mode="widthFix"></image>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script lang="ts" setup>
+  import { ProductSimpleType } from '@/types/product-type'
+
+  defineOptions({
+    name: 'ProductItem',
+  })
+  const { product } = defineProps<{ product: ProductSimpleType }>()
+</script>
+
+<style lang="scss" scoped>
+  .product-item-container {
+    position: relative;
+    width: 328rpx;
+    margin-bottom: 26rpx;
+
+    .is-collect {
+      position: absolute;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 64rpx;
+      height: 64rpx;
+      background-color: $shop-white;
+    }
+
+    .product-name {
+      margin-top: 16rpx;
+      font-family: 'PingFang SC';
+      font-size: 28rpx;
+      font-style: normal;
+      font-weight: 600;
+      line-height: 30rpx;
+      color: $shop-text-3;
+    }
+
+    .sell-rate {
+      display: flex;
+      align-items: center;
+      margin-top: 16rpx;
+      font-family: 'PingFang SC';
+      font-size: 24rpx;
+      font-style: normal;
+      font-weight: 400;
+      line-height: 28rpx;
+      color: $shop-text-9;
+
+      .rate {
+        display: flex;
+        margin-right: 16rpx;
+      }
+
+      .sold {
+        box-sizing: border-box;
+        padding-left: 16rpx;
+        border-left: 2rpx solid $shop-bg-line;
+      }
+    }
+
+    .price-cart {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      font-family: 'PingFang SC';
+      font-size: 28rpx;
+      font-style: normal;
+      font-weight: 600;
+      line-height: 48rpx; /* 157.143% */
+      color: $shop-primary;
+
+      .cart {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 48rpx;
+        height: 48rpx;
+        background-color: $shop-primary;
+        border-radius: 50%;
+      }
+    }
+  }
+</style>

+ 27 - 0
src/components/product-list/product-list.vue

@@ -0,0 +1,27 @@
+<template>
+  <view class="product-list-container">
+    <ProductItem v-for="item in productList" :key="item.id" :product="item"></ProductItem>
+  </view>
+</template>
+
+<script lang="ts" setup>
+  import { ProductSimpleType } from '@/types/product-type'
+  import data from './data.json'
+  import ProductItem from './product-item.vue'
+
+  defineOptions({
+    name: 'ProductList',
+  })
+
+  const productList = ref<ProductSimpleType[]>(data)
+</script>
+
+<style lang="scss" scoped>
+  .product-list-container {
+    box-sizing: border-box;
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    padding-right: 32rpx;
+  }
+</style>

+ 5 - 0
src/static/images/cart.svg

@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
+  <path d="M1.33333 2.66663H2.49999L2.99999 4.66663M2.99999 4.66663L4.66666 11.3333H13.3333L15 4.66663H2.99999Z" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+  <path d="M4.66667 14.6665C5.21896 14.6665 5.66667 14.2188 5.66667 13.6665C5.66667 13.1142 5.21896 12.6665 4.66667 12.6665C4.11439 12.6665 3.66667 13.1142 3.66667 13.6665C3.66667 14.2188 4.11439 14.6665 4.66667 14.6665Z" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+  <path d="M13.3335 14.6665C13.8858 14.6665 14.3335 14.2188 14.3335 13.6665C14.3335 13.1142 13.8858 12.6665 13.3335 12.6665C12.7812 12.6665 12.3335 13.1142 12.3335 13.6665C12.3335 14.2188 12.7812 14.6665 13.3335 14.6665Z" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 9 - 0
src/static/images/rate.svg

@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="15" viewBox="0 0 14 15" fill="none">
+  <path d="M6.64786 2.01881C6.79229 1.72615 7.20961 1.72615 7.35404 2.01881L8.92964 5.21129L12.4527 5.72322C12.7757 5.77015 12.9047 6.16704 12.671 6.39484L10.1216 8.87983L10.7234 12.3887C10.7786 12.7104 10.4409 12.9557 10.1521 12.8038L7.00095 11.1471L3.84979 12.8038C3.56093 12.9557 3.22331 12.7104 3.27848 12.3887L3.8803 8.87983L1.33095 6.39484C1.09726 6.16704 1.22622 5.77015 1.54918 5.72322L5.07228 5.21129L6.64786 2.01881Z" fill="url(#paint0_linear_2633_455)"/>
+  <defs>
+    <linearGradient id="paint0_linear_2633_455" x1="12.7903" y1="7.3246" x2="1.21162" y2="7.3246" gradientUnits="userSpaceOnUse">
+      <stop stop-color="#FF4C1B"/>
+      <stop offset="1" stop-color="#FC7B1C"/>
+    </linearGradient>
+  </defs>
+</svg>

+ 11 - 0
src/types/product-type.ts

@@ -0,0 +1,11 @@
+// 商品列表结构类型
+export interface ProductSimpleType {
+  id: number // 商品id
+  name: string // 商品名称
+  price: number // 商品价格
+  cover: string // 商品封面
+  category: string // 商品分类
+  rate: number // 商品评分
+  sold: number // 商品销量
+  isCollect?: boolean // 是否收藏
+}