1. 项目概述:为什么选择“车之家”购物商城作为期末大作业
作为一个过来人,我太了解大学生期末大作业的痛点了 —— 既要体现技术广度,又要保证功能完整,还不能太复杂导致做不完。HTML+CSS+JavaScript 三件套是前端基础,但很多同学交上去的作业要么是静态页面拼凑,要么是功能残缺的“半成品”。这个“车之家”购物商城选题,我一开始就觉得挺聪明的:汽车相关品类自带“专业感”,能让老师眼前一亮,而且购物商城的核心流程(商品展示、购物车、结算)天然适合练手,正好覆盖了前端三大件的主要知识点。
这个项目本质上是一个纯前端模拟的购物商城,不需要后端支持,所有数据(商品信息、购物车状态)都存储在 JavaScript 的变量或 localStorage 中。适合刚学完 JS 基础、想做一个完整项目来巩固技能的同学。整个项目可以从零开始手写,不依赖任何第三方框架(如 Vue、React),让你彻底吃透原生 DOM 操作和事件处理。做完这个项目,你至少能掌握:语义化 HTML 结构、CSS 布局与动画(Flex、Grid、过渡)、JavaScript 数组方法与对象操作、事件冒泡与委托、本地存储(localStorage)的使用。这些知识点在后续的框架学习中都是基础中的基础。
我见过太多同学直接拷贝网上现成的商城模板,结果答辩时一问三不知。所以这篇博文会带你一步步自己构建,从页面设计到交互逻辑,把每个“为什么这样做”都讲清楚。你不需要有后端知识,只要懂一点 HTML 标签、CSS 选择器、JS 的基本语法,就能跟着做出来。当然,如果你已经有一些基础,可以直接跳到“核心交互实现”部分,参考购物车的逻辑设计。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 整体设计与技术选型:一个“车之家”商城应该长什么样
2.1 页面结构规划:从用户视角出发
一个购物商城,用户最关心的无非是“看商品”、“加购物车”、“下单”。所以我们的页面结构围绕这三个核心场景展开:
- 首页(商品列表页):展示所有汽车相关商品,包括图片、名称、价格、添加到购物车按钮。这里要体现视觉吸引力,因为汽车周边产品往往有酷炫的图片(比如轮毂、车模、机油、内饰件等)。
- 购物车页:展示已添加的商品,支持数量修改、删除、总价计算。这个页面是交互的核心,也是 JS 逻辑最密集的地方。
- 结算页(模拟):因为纯前端无法真正下单,用弹窗或页面显示“订单提交成功”的提示,并清空购物车。重点是模拟流程的完整性。
我选择将商品列表放在首页,购物车作为一个独立页面(或侧边栏)。考虑到期末作业的展示效果,我推荐使用“单页多视图”架构:所有内容都在一个 HTML 文件中,通过 CSS 控制显示/隐藏,或者用 JS 切换区域。这样代码更紧凑,也方便老师检查。当然,你也可以拆成多个 HTML 页面,但那样需要处理页面间数据传递(用 URL 参数或 localStorage),会增加复杂度。对于新手,单页应用更友好。
2.2 技术栈选型:为什么不用框架
- HTML5:语义化标签(header、nav、main、section、footer)让结构清晰,也有利于 SEO 和可访问性。对于期末作业,使用语义化标签是个加分项。
- CSS3:Flexbox 和 Grid 用于布局,配合过渡动画(hover 效果、购物车抽屉滑入)提升用户体验。不需要 Bootstrap 等框架,因为手写 CSS 能体现你对布局的理解。而且车之家主题可以设计深色/金属质感配色,更容易出彩。
- 原生 JavaScript(ES6+):使用 let/const、箭头函数、模板字符串、数组方法(map、filter、reduce)等,既现代又简洁。用 localStorage 持久化购物车数据,即使刷新页面,购物车内容也不会丢失。
不选择 Vue/React 的原因:期末大作业通常要求展示基础能力,框架会掩盖原生基本功。而且很多老师明确禁止使用框架,要求手写原生。但如果你有基础,想展示学习能力,可以额外加一个基于框架的版本作为对比,不过主体还是原生。
2.3 数据模型设计:用对象数组模拟数据库
在 JavaScript 中,我们用一个数组来存储所有商品信息。每个商品是一个对象,包含 id、名称、图片、价格、分类等属性。例如:
javascript复制const products = [
{
id: 1,
name: '赛车座椅靠垫',
image: 'images/seat.jpg',
price: 299,
category: '内饰'
},
{
id: 2,
name: '全合成机油 5W-30',
image: 'images/oil.jpg',
price: 198,
category: '保养'
}
// 更多商品...
];
购物车数据则是一个数组,每个元素包含商品 id、数量。计算总价时通过 id 从 products 中查找价格。这种设计让数据与视图分离,购物车只需存储 id 和数量,减少冗余。
javascript复制let cart = [
{ id: 1, quantity: 2 },
{ id: 3, quantity: 1 }
];
这样设计的好处是:当商品信息(如价格)变化时,购物车自动同步最新价格,不需要手动更新每个购物车项。而且容易扩展,比如添加商品介绍、库存等字段。
3. 核心细节解析与实操要点
3.1 HTML 结构搭建:从骨架到填充
先设计整体布局。我习惯用“头-主体-尾”结构,主体内分左右(或上下)区域。对于首页,商品列表用网格展示。购物车区域可以放在页面右侧固定位置,或者用按钮触发弹窗。
示例 HTML 结构(简化版):
html复制<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>车之家 - 汽车用品购物商城</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<div class="logo">车之家</div>
<nav>
<ul>
<li><a href="#" data-page="home">首页</a></li>
<li><a href="#" data-page="cart">购物车 (<span id="cart-count">0</span>)</a></li>
</ul>
</nav>
</header>
<main>
<!-- 首页商品列表区域 -->
<section id="home-page" class="page active">
<div class="product-grid" id="product-grid">
<!-- 由 JS 动态生成 -->
</div>
</section>
<!-- 购物车页面区域 -->
<section id="cart-page" class="page">
<div id="cart-content">
<!-- 购物车列表 -->
</div>
<div id="cart-total">
总计:<span id="total-price">0</span> 元
<button id="checkout-btn">结算</button>
</div>
</section>
</main>
<footer>
<p>© 2025 车之家 期末大作业</p>
</footer>
<script src="script.js"></script>
</body>
</html>
注意点:
- 使用
data-page属性配合 JS 控制页面切换,比直接操作 href 更优雅。 - 购物车数量徽标(
#cart-count)实时更新,需要动态绑定。 - 商品列表区域留空,由 JS 渲染,避免硬编码重复 HTML。
3.2 CSS 布局与样式设计:让“车之家”有质感
汽车主题的视觉风格通常偏向硬朗、金属、深色,但作为大学生作业,也可以走简洁清爽路线,关键是要干净。我选择了深灰+橙色的配色方案,深灰作为背景,橙色作为按钮和强调色,呼应“车之家”的动感。
布局上,商品网格使用 CSS Grid:
css复制.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
padding: 20px;
}
这样能自适应屏幕宽度,每行最少 250px,自动填充。购物车页面则使用 Flex 布局,左边列表,右边结算区(或上下结构)。
为了让过渡更平滑,我添加了页面切换动画。当两个页面切换时,用 opacity 和 transform 实现淡入淡出效果。
css复制.page {
display: none;
opacity: 0;
transition: opacity 0.3s ease;
}
.page.active {
display: block;
opacity: 1;
}
注意:display 无法直接动画,所以这里用 display: none 隐藏,但 active 时用 block 显示,再用 opacity 过渡。不过更好的做法是用 visibility 和 opacity 配合,或者用 position: absolute 叠加。我倾向于用 display: none 加 opacity 的简单模式,因为对于期末作业,效果已经足够。
商品卡片样式设计:
css复制.product-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
overflow: hidden;
transition: transform 0.2s, box-shadow 0.2s;
}
.product-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.15);
}
.product-card img {
width: 100%;
height: 200px;
object-fit: cover;
}
.product-card .info {
padding: 15px;
}
.product-card .info h3 {
margin: 0 0 10px;
font-size: 18px;
}
.product-card .info .price {
color: #e67e22;
font-size: 20px;
font-weight: bold;
}
.product-card .add-to-cart {
display: block;
width: 100%;
padding: 10px;
background: #e67e22;
color: #fff;
border: none;
border-radius: 0 0 8px 8px;
cursor: pointer;
transition: background 0.2s;
}
.product-card .add-to-cart:hover {
background: #d35400;
}
这里要注意:图片必须使用 object-fit: cover 来适应容器,避免图片变形。同时,每个商品卡片应该包含一个“加入购物车”按钮,按钮通过自定义属性 data-product-id 绑定商品 ID,方便 JS 事件委托。
