上一篇文章完成了基础的商品列表:Vue3.0 简单商城—商品列表组件 – 每天进步一点点
这篇文章介绍一下购物车组件。
基本逻辑:当我们点击“加入购物车时”,会把相应的产品加入到购物车中。
一、修改商品列表组件
我们修改商品列表组件,完善“加入购物车”功能,使用户点击“加入购物车”时,可以将相应的数据存入到本地缓存中。
先修改商品信息,增加num 字段,用来表示商品的数量。
id:'1003',
name: '西瓜',
price: 30,
description: '新鲜的大西瓜',
image: 'https://img2.baidu.com/it/u=3734188370,3061921446&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200',
num:0,
那么,整个商品列表组件修改为如下:
<template>
<div>
<el-row :gutter="20">
<el-col :span="6" v-for="(product, index) in products" :key="index">
<el-card :body-style="{ padding: '0px' }" class="product-card">
<img :src="product.image" class="image" />
<div style="padding: 14px">
<span>{{ product.name }}</span>
<div class="bottom">
<span class="price">¥{{ product.price }}</span>
<el-button type="text" class="button">查看详情</el-button>
<el-button type="text" class="button" @click="addToCar(product)"
>加入购物车</el-button
>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
// import homeApi from "../../api/homeApi";
export default {
data() {
return {
products: [
{
id: "1001",
name: "草莓",
price: 37,
description: "新鲜的大草莓",
image:
"https://img0.baidu.com/it/u=1884825130,1214737831&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
num: 0,
},
{
id: "1002",
name: "苹果",
price: 15,
description: "新鲜的苹果",
image:
"https://img0.baidu.com/it/u=3289470460,166095271&fm=253&fmt=auto&app=120&f=JPEG?w=183&h=183",
num: 0,
},
{
id: "1003",
name: "西瓜",
price: 30,
description: "新鲜的大西瓜",
image:
"https://img2.baidu.com/it/u=3734188370,3061921446&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
num: 0,
},
{
id: "1004",
name: "香蕉",
price: 8.5,
description: "新鲜的香蕉",
image:
"https://img0.baidu.com/it/u=3106970920,4028332390&fm=253&fmt=auto&app=120&f=JPEG?w=193&h=193",
num: 0,
},
{
id: "1005",
name: "哈密瓜",
price: 17,
description: "新鲜的哈密瓜",
image:
"https://img1.baidu.com/it/u=3415357883,3105635612&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
num: 0,
},
],
};
},
methods: {
//添加到购物车(使用localStorage存储)
addToCar(e) {
this.$message.success('添加'+e.name+"到购物车成功");
//console.log(e);
//根据id,每有一个,就增加一个num属性,
let flag = false;
//先检查有没有这个数据
if (localStorage.getItem("carList")) {
let carList = [];
carList = JSON.parse(localStorage.getItem("carList"));
console.log(carList);
//看看数组里面有没有当前这个数组
for (let index = 0; index < carList.length; index++) {
const element = carList[index];
//console.log(element);
if (e.id == element.id) {
carList[index].num++;
flag = true; //能匹配上
}
console.log(carList[index]);
}
if (flag == false) {
//没有匹配就新增
carList.push(e);
}
localStorage.setItem("carList", JSON.stringify(carList));
} else {
let carList = [];
carList.push(e);
localStorage.setItem("carList", JSON.stringify(carList)); // 将数据存入到本地存储中。
}
},
},
mounted() {
//homeApi.methods.getWeather(101120201);
},
};
</script>
<style >
.product-card {
margin-bottom: 20px;
}
.image {
width: 100%;
display: block;
}
.bottom {
margin-top: 13px;
line-height: 12px;
display: flex;
justify-content: space-between;
align-items: center;
}
.price {
font-size: 18px;
color: #f56c6c;
}
.button {
padding: 0;
min-height: auto;
}
</style>
效果如下:

二、购物车组件
购物车组件的基本逻辑是:当组件加载时,先从本地缓存中获取购物车数据,然后将数据渲染到页面上,最后统一计算数据。
我们使用table组件来表示购物车功能。
基础参考代码如下:
<template>
<div>
<el-card>
<el-table :data="cart" style="width: 100%">
<el-table-column
prop="name"
label="商品名称"
width="180"
></el-table-column>
<el-table-column
prop="price"
label="价格"
width="180"
></el-table-column>
<el-table-column label="数量" prop="num">
<template v-slot="scope">
<el-input-number
v-model="scope.row.num"
:min="1"
:max="99"
@change="updateTotalPrice"
></el-input-number>
</template>
</el-table-column>
<el-table-column label="操作">
<template v-slot="scope">
<el-button @click="removeFromCart(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-row :gutter="20">
<el-col :span="12">总价: {{ totalPrice }}</el-col>
<el-col :span="12">
<el-button type="primary">合并付款</el-button></el-col>
</el-row>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
cart: [], //购物车数据
totalPrice:0
};
},
components: {},
methods: {},
mounted() {
if (localStorage.getItem("carList")) {
this.cart = JSON.parse(localStorage.getItem("carList"));
//初次加载需要计算价格
var sum=0
for (let index = 0; index < this.cart .length; index++) {
const element = this.cart [index];
sum+=element.price * element.num;
}
this.totalPrice=sum;
}
},
};
</script>
<style >
</style>

三、完善数量变化与删除操作
我们增加计算总价格的函数:
//重新计算价格的方法:
caclPrice(){
var sum=0
for (let index = 0; index < this.cart .length; index++) {
const element = this.cart [index];
sum+=element.price * element.num;
}
this.totalPrice=sum;
},
那么不论我们是删除数据,还是更新商品的数量,都会重新计算价格。
参考代码如下:
vue.car
<template>
<div>
<el-card>
<el-table :data="cart" style="width: 100%">
<el-table-column
prop="name"
label="商品名称"
width="180"
></el-table-column>
<el-table-column
prop="price"
label="价格"
width="180"
></el-table-column>
<el-table-column label="数量" prop="num">
<template v-slot="scope">
<el-input-number
v-model="scope.row.num"
:min="1"
:max="99"
@change="updateTotalPrice()"
></el-input-number>
</template>
</el-table-column>
<el-table-column label="操作">
<template v-slot="scope">
<el-button @click="removeFromCart(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-row :gutter="20">
<el-col :span="12">总价: {{ totalPrice }}</el-col>
<el-col :span="12">
<el-button type="primary">合并付款</el-button></el-col>
</el-row>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
cart: [], //购物车数据
totalPrice:0
};
},
components: {},
methods: {
//移除一条数据
removeFromCart(row){
const index = this.cart.findIndex(item => item.id === row.id);
if (index !== -1) {
this.cart.splice(index, 1);
//重新计算价格
this.caclPrice()
//更新缓存数据
localStorage.setItem("carList", JSON.stringify(this.cart));
}
},
//重新计算价格的方法:
caclPrice(){
var sum=0
for (let index = 0; index < this.cart .length; index++) {
const element = this.cart [index];
sum+=element.price * element.num;
}
this.totalPrice=sum;
},
updateTotalPrice(){
console.log(11)
//重新计算价格
this.caclPrice()
//更新缓存
localStorage.setItem("carList", JSON.stringify(this.cart));
}
},
mounted() {
if (localStorage.getItem("carList")) {
this.cart = JSON.parse(localStorage.getItem("carList"));
//初次加载需要计算价格
var sum=0
for (let index = 0; index < this.cart .length; index++) {
const element = this.cart [index];
sum+=element.price * element.num;
}
this.totalPrice=sum;
}
},
};
</script>
<style >
</style>
效果如下:
