深度分析Vue基础教程之网上购物商城开发实战
引言:为啥我们要跟“购物车”过不去?
嘿,屏幕前的你!是不是已经看完了Vue的官方文档,脑子里的v-for和v-if已经开始打架了?感觉啥都会了,但一打开代码编辑器,却不知道从何下手?
相信我,你不是一个人!学习任何编程框架,最大的坎儿就是从理论到实践的“惊险一跃”。而“网上购物商城”,简直就是为Vue量身定做的实战练习题!它几乎覆盖了Vue最核心、最基础的所有知识点,而且逻辑清晰,贴近生活,理解起来毫无压力。
今天,咱就不整那些虚头巴脑的概念了。我直接化身你的项目搭档,咱们一起,用Vue的基础语法,从零开始,搭建一个属于我们自己的“剁手乐园”。放心,过程绝对好玩,包教包会,代码可以直接“偷走”那种!
第一章:开工前,咱们得先把“摊位”支棱起来(项目初始化)
想象一下,你要开个网店,总得先有个门面吧?对于Vue项目来说,这个门面就是我们的开发环境。
1.1 创建Vue项目
咱们直接用Vue官方推荐的脚手架工具create-vue,省心又省力。打开你的终端(Terminal),输入以下命令:
npm create vue@latest my-online-shop
然后一路按照提示选择就行(对于初学者,暂时不用选Router和Pinia,我们后面手动加,这样理解更深)。创建完成后,进入项目文件夹,安装依赖,并启动开发服务器:
cd my-online-shop
npm install
npm run dev
看到 http://localhost:5173 上跑起来一个默认页面?恭喜你,你的“数字商铺”地基已经打好了!
1.2 清理与规划
把src/components和App.vue里默认的内容清一清,咱们要开始画自己的蓝图了。
我们这个迷你商城需要哪些“功能区”呢?
- 商品展示区(ProductList): 用来摆出我们的商品。
- 购物车(ShoppingCart): 存放用户想买的宝贝。
- 导航栏(NavBar): 方便用户在商品区和购物车之间切换。
看,这就是Vue组件化思想的雏形——把一个复杂的页面,拆分成一个个独立、可复用的小部件。
第二章:上货!用v-for把商品“摆”上架
店开好了,不能空着啊!咱们得进货。
2.1 准备商品数据
在App.vue里,我们用data选项来当我们的“仓库管理员”,管理所有商品信息。
<!-- App.vue -->
<template>
<div id="app">
<NavBar />
<!-- 主要内容区域,后面会根据路由切换 -->
<router-view />
</div>
</template>
<script>
import NavBar from './components/NavBar.vue'
export default {
name: 'App',
components: {
NavBar
},
// 这里是我们的“数据仓库”
data() {
return {
products: [
{ id: 1, name: 'Vue信仰咖啡杯', price: 88, image: '/images/cup.jpg', inventory: 10 },
{ id: 2, name: 'React求生手册', price: 66, image: '/images/book.jpg', inventory: 5 },
{ id: 3, name: 'JavaScript防脱发洗发水', price: 128, image: '/images/shampoo.jpg', inventory: 2 },
{ id: 4, name: 'CSS魔法指南', price: 99, image: '/images/css-book.jpg', inventory: 8 },
],
cart: [] // 购物车,一开始是空的
}
},
// 注意:这里我们暂时没有引入Vuex/Pinia,所以用provide来向下传递数据
provide() {
return {
globalData: {
products: this.products,
cart: this.cart
}
}
}
}
</script>
2.2 创建商品列表组件
新建src/components/ProductList.vue,是时候展示v-for的真正技术了!
<!-- components/ProductList.vue -->
<template>
<div class="product-list">
<h2>欢迎光临,随便看看!</h2>
<div class="products">
<!-- v-for 循环渲染每一个商品 -->
<div v-for="product in products" :key="product.id" class="product-card">
<img :src="product.image" :alt="product.name" />
<h3>{{ product.name }}</h3>
<p class="price">¥{{ product.price }}</p>
<p class="inventory">库存: {{ product.inventory }}</p>
<!-- 绑定点击事件,将当前商品传入addToCart方法 -->
<button @click="addToCart(product)" :disabled="product.inventory === 0">
{{ product.inventory === 0 ? '售罄' : '加入购物车' }}
</button>
</div>
</div>
</div>
</template>
<script>
export default {
inject: ['globalData'], // 接收从App.vue传递下来的全局数据
computed: {
products() {
return this.globalData.products;
}
},
methods: {
addToCart(product) {
// 这里就是Vue的响应式魅力所在!
// 我们直接操作数据,视图会自动更新
if (product.inventory > 0) {
// 检查购物车是否已有该商品
const itemInCart = this.globalData.cart.find(item => item.id === product.id);
if (itemInCart) {
itemInCart.quantity++;
} else {
this.globalData.cart.push({ ...product, quantity: 1 });
}
// 减少库存
product.inventory--;
alert(`成功将 ${product.name} 加入购物车!`);
}
}
}
}
</script>
<style scoped>
.products {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.product-card {
border: 1px solid #ddd;
padding: 15px;
border-radius: 8px;
width: 200px;
text-align: center;
}
.product-card img {
width: 100%;
height: 150px;
object-fit: cover;
}
.price {
color: #e44d26;
font-weight: bold;
font-size: 1.2em;
}
</style>
深度分析:
看到没?v-for就像是一个“复印机”,根据products数组,一口气复印出N个商品卡片。:key="product.id"是给每个复印件一个独一无二的身份证,让Vue能高效地跟踪每个节点,这可是性能优化的关键点!而@click="addToCart(product)"则完美体现了数据驱动视图的思想:我们不用手动去操作DOM(比如document.createElement),只需要修改cart数组和inventory库存,页面上按钮的状态、库存显示、购物车数量等,全都会自动、神奇地更新!
第三章:核心玩法——购物车与计算属性
购物车可是商城的灵魂,这里面的“算计”可多了。
3.1 创建购物车组件
新建src/components/ShoppingCart.vue。
<!-- components/ShoppingCart.vue -->
<template>
<div class="shopping-cart">
<h2>你的购物车</h2>
<div v-if="cart.length === 0">购物车空空如也,快去逛逛吧!</div>
<div v-else>
<div v-for="item in cart" :key="item.id" class="cart-item">
<span>{{ item.name }}</span>
<span>¥{{ item.price }}</span>
<div class="quantity-controls">
<button @click="decreaseQuantity(item)">-</button>
<span>{{ item.quantity }}</span>
<button @click="increaseQuantity(item)" :disabled="item.inventory <= 0">+</button>
</div>
<span小计:¥{{ item.price * item.quantity }}</span>
<button @click="removeFromCart(item)" class="remove-btn">删除</button>
</div>
<!-- 这里是计算属性的用武之地! -->
<div class="cart-total">
<strong>总价:¥{{ cartTotalPrice }}</strong>
</div>
<button @click="checkout">一键下单</button>
</div>
</div>
</template>
<script>
export default {
inject: ['globalData'],
computed: {
cart() {
return this.globalData.cart;
},
// 计算属性:自动计算总价,依赖变化它会自动重新计算
cartTotalPrice() {
return this.cart.reduce((total, item) => total + (item.price * item.quantity), 0);
}
},
methods: {
increaseQuantity(item) {
if (item.inventory > 0) {
item.quantity++;
// 找到原商品,减少库存
const originalProduct = this.globalData.products.find(p => p.id === item.id);
originalProduct.inventory--;
}
},
decreaseQuantity(item) {
item.quantity--;
// 找到原商品,增加库存
const originalProduct = this.globalData.products.find(p => p.id === item.id);
originalProduct.inventory++;
// 如果数量减到0,就从购物车移除
if (item.quantity === 0) {
this.removeFromCart(item);
}
},
removeFromCart(item) {
const index = this.cart.indexOf(item);
if (index > -1) {
// 归还库存
const originalProduct = this.globalData.products.find(p => p.id === item.id);
originalProduct.inventory += item.quantity;
// 从购物车移除
this.cart.splice(index, 1);
}
},
checkout() {
if (this.cart.length > 0) {
alert(`下单成功!总计:¥${this.cartTotalPrice}。感谢您的光临!`);
// 清空购物车
this.cart.length = 0;
}
}
}
}
</script>
<style scoped>
.cart-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #eee;
}
.quantity-controls {
display: flex;
align-items: center;
gap: 10px;
}
.remove-btn {
background-color: #ff4757;
color: white;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
}
</style>
深度分析:
computed(计算属性)在这里扮演了“财务总监”的角色。它依赖于cart数组,当cart里的商品数量或单价任何一项发生变化时,cartTotalPrice会自动、高效地重新计算总价。你不需要手动去调用它,Vue的响应式系统会帮你搞定一切。这比在methods里写一个方法然后在模板里调用 getTotalPrice() 要优雅和高效得多,因为它有缓存。
第四章:让页面“动”起来——Vue Router路由配置
一个商城不能只有一个页面啊,我们得让用户能在“商品列表”和“购物车”之间来回切换。
4.1 安装和配置路由
首先,安装Vue Router:
npm install vue-router@4
然后,创建src/router/index.js文件:
// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import ProductList from '../components/ProductList.vue';
import ShoppingCart from '../components/ShoppingCart.vue';
const routes = [
{ path: '/', component: ProductList },
{ path: '/cart', component: ShoppingCart },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
4.2 修改主入口和导航栏
在main.js中引入并使用路由:
// main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router' // 导入路由配置
createApp(App).use(router).mount('#app') // 使用路由
创建导航栏组件src/components/NavBar.vue:
<!-- components/NavBar.vue -->
<template>
<nav class="navbar">
<h1>我的Vue小店</h1>
<div class="nav-links">
<!-- 使用 router-link 组件进行导航 -->
<router-link to="/">商品列表</router-link>
<router-link to="/cart">
购物车
<!-- 这里可以显示购物车商品总数,又是一个计算属性的好用例! -->
<span class="cart-count" v-if="cartItemCount > 0">({{ cartItemCount }})</span>
</router-link>
</div>
</nav>
</template>
<script>
export default {
inject: ['globalData'],
computed: {
cartItemCount() {
// 计算购物车里所有商品的数量总和
return this.globalData.cart.reduce((count, item) => count + item.quantity, 0);
}
}
}
</script>
<style scoped>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
.nav-links {
display: flex;
gap: 20px;
}
.router-link-active {
font-weight: bold;
color: #e44d26;
}
.cart-count {
background-color: #e44d26;
color: white;
border-radius: 50%;
padding: 2px 6px;
font-size: 0.8em;
}
</style>
深度分析:
Vue Router让我们的应用变成了单页面应用(SPA)。当你点击<router-link>时,并不会刷新整个页面,而是由Router在背后悄悄地切换<router-view>里的组件。这带来了极其流畅的用户体验。导航栏上那个动态变化的购物车数量({{ cartItemCount }}),再次展现了计算属性和响应式数据的威力。
第五章:总结与升华——你的Vue第一课毕业了
到这里,一个具备核心功能的迷你网上购物商城就完成了!我们来复盘一下,都用到了哪些Vue基础知识:
- 响应式数据(
data):products和cart是整个应用的心脏,它们一变,视图自动更新。 - 模板语法与指令:
{{ }}插值、v-for列表渲染、v-if条件渲染、v-bind(:)属性绑定、v-on(@)事件绑定。这是Vue的“肌肉”,负责把数据和DOM连接起来。 - 组件化:将UI拆分为独立、可复用的
ProductList、ShoppingCart、NavBar组件,让代码结构清晰,易于维护。 - 计算属性(
computed):用于进行依赖数据的复杂计算,如总价、商品总数,它有缓存,效率高。 - 方法(
methods):处理用户交互产生的逻辑,如添加商品、增减数量。 - Vue Router:管理前端路由,实现多页面切换的体验。
下一步可以做什么?
- 状态管理: 当应用再复杂一点,
provide/inject可能会显得力不从心,这时可以引入Pinia来更科学地管理全局状态。 - UI库: 自己写CSS太麻烦?可以引入像Element Plus、Vant这样的UI库,快速搭建美观的界面。
- 后端连接: 使用Axios从真实的服务器API获取商品数据,而不是写死在代码里。
- 动画: 用Vue的
<Transition>组件给商品加入购物车、页面切换添加丝滑的动画效果。
记住,这个项目虽然小,但它几乎包含了前端MVVM框架最精髓的思想。理解了它,你再去看其他更复杂的Vue项目,或者甚至去学习React、Angular,都会觉得触类旁通。
所以,别光看,赶紧打开你的代码编辑器,亲手敲一遍吧!遇到Bug不要慌,那正是你成长最快的时候。祝你“云剁手”愉快,编程之路越走越顺!
Vue购物车实战入门
6864

被折叠的 条评论
为什么被折叠?



