Vue购物车综合案例
Vue购物车综合案例
1. 演示效果
2. 代码分析
2.1. 创建 5 行 5 列的表格
创建的时候可以先用静态的数据,后面再添加需要的数据。
<!-- 1.创建表格 -->
<table border="true" cellspacing="0">
<!-- 表格头 -->
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<!--判断购物车中是否没有商品,如果是,则显示提示信息。-->
<tbody v-if="bookList.length === 0">
<tr>
<td colspan="5">购物车中没有商品</td>
</tr>
</tbody>
<!-- 表格体 -->
<tbody v-else>
<!-- 遍历表格行,将数据填入 -->
<tr v-for="(item, index) in bookList" :key="item.id">
<td>{{ index + 1 }}</td>
<td>{{ item.productName }}</td>
<td>{{ item.productPrice }}</td>
<td>
<button @click="controlNum(item, 'decrease')">-</button>
{{ item.productCount }}
<button @click="controlNum(item, 'add')">+</button>
</td>
<td><button @click='deleteItem(item)'>移除</button></td>
</tr>
<tr>
<td colspan="5">总价格:¥{{ sum }}</td>
</tr>
</tbody>
</table>
使用v-if
指令来判断购物车中是否没有商品,如果是,则显示提示信息,如果没有,则显示购物车中没有商品。
<tbody v-if="bookList.length === 0">
<tr>
<td colspan="5">购物车中没有商品</td>
</tr>
</tbody>
通过border="true"
和cellspacing="0"
属性设置了边框和 cell 的间距。
<table border="true" cellspacing="0">
给表格设置整体样式。
<style scoped>
/* 添加scoped,不会和其他组件发生样式冲突 */
.purchase {
margin: auto;
}
table {
border-color: #ccc;
}
table td,
th {
padding: 10px 20px;
}
table th {
background-color: #ddd;
}
2.2. 异步获取书籍列表
用axios
发送 HTTP GET 请求到服务器,来获取服务器的数据,并使用v-for
添加到表格中。
// 2.从服务器获取书籍列表
async mounted() {
// 2.1用await关键字来控制执行流程,确保数据获取完成后才进行后续操作。
const bookList = await axios.get('http://39.103.151.139:8000/cart')
const { status, data } = bookList
// 2.2如果请求成功(状态码为200),则将书籍列表数据赋值给this.bookList。
if (status === 200) {
this.bookList = data
}
},
<tr v-for="(item, index) in bookList" :key="item.id">
2.3. 计算总的价格
使用computed
进行计算总的价格,需要先获取书籍的价格和数量,再使用reduce
进行求和,最后结果保留两位数字,加载到表格中。
// 3.计算总的价格
computed: {
sum() {
// 3.1 获取书籍的价格和数量
// 将bookList转化为整数的数组
const result = this.bookList
.map((book) => {
const { productPrice, productCount } = book;
return productPrice * productCount;
})
// 3.2使用reduce求和
.reduce((a, b) => a + b, 0)
// console.log(result);
// 3.3 保留两位小数
return result.toFixed(2);
},
},
<tr>
<td colspan="5">总价格:¥{{ sum }}</td>
</tr>
2.4. 商品数量加或减
可以使用map
来修改整个书籍的数据,通过加或减的类型,来确定数量的增加或减少,还要确保购买数量大于 0。
// 4.商品数量加或减
controlNum(item, type) {
// 4.1使用map修改整个bookList数据
this.bookList = this.bookList.map(book => {
let res = book
// 4.2判断传入的类型
let count = type === 'add' ? book.productCount + 1 : book.productCount - 1
// 4.3找到当前我们要修改的项,然后让购买数量-1,购买数量大于0
if (book.id === item.id && count > 0) {
res = {
...item,
productCount: count
}
}
return res
})
},
2.5. 移除表格行内容
使用filter
过滤掉要删除的项。
// 5.移除表格行内容
deleteItem(item) {
// 使用filter过滤掉要删除的项
this.bookList = this.bookList.filter(book => {
return book.id !== item.id
})
}
3. 代码实现
<template>
<div class="purchase">
<div class="header">购物车</div>
<!-- 1.创建表格 -->
<table border="true" cellspacing="0">
<!-- 表格头 -->
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody v-if="bookList.length === 0">
<tr>
<td colspan="5">购物车中没有商品</td>
</tr>
</tbody>
<!-- 表格体 -->
<tbody v-else>
<!-- 遍历表格行,将数据填入 -->
<tr v-for="(item, index) in bookList" :key="item.id">
<td>{{ index + 1 }}</td>
<td>{{ item.productName }}</td>
<td>{{ item.productPrice }}</td>
<td>
<button @click="controlNum(item, 'decrease')">-</button>
{{ item.productCount }}
<button @click="controlNum(item, 'add')">+</button>
</td>
<td><button @click="deleteItem(item)">移除</button></td>
</tr>
<tr>
<td colspan="5">总价格:¥{{ sum }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "PurchaseCar",
data() {
return {
bookList: [],
};
},
// 2.从服务器获取书籍列表
async mounted() {
// 2.1用await关键字来控制执行流程,确保数据获取完成后才进行后续操作。
const bookList = await axios.get("http://39.103.151.139:8000/cart");
const { status, data } = bookList;
// 2.2如果请求成功(状态码为200),则将书籍列表数据赋值给this.bookList。
if (status === 200) {
this.bookList = data;
}
},
// 3.计算总的价格
computed: {
sum() {
// 3.1 获取书籍的价格和数量
// 将bookList转化为整数的数组
const result = this.bookList
.map((book) => {
const { productPrice, productCount } = book;
return productPrice * productCount;
})
// 3.2使用reduce求和
.reduce((a, b) => a + b, 0);
// console.log(result);
// 3.3 保留两位小数
return result.toFixed(2);
},
},
methods: {
// 4.商品数量加或减
controlNum(item, type) {
// 4.1使用map修改整个bookList数据
this.bookList = this.bookList.map((book) => {
let res = book;
// 4.2判断传入的类型
let count =
type === "add"
? book.productCount + 1
: book.productCount - 1;
// 4.3找到当前我们要修改的项,然后让购买数量-1,购买数量大于0
if (book.id === item.id && count > 0) {
res = {
...item,
productCount: count,
};
}
return res;
});
},
// 5.移除表格行内容
deleteItem(item) {
// 5.1使用filter过滤掉要删除的项
this.bookList = this.bookList.filter((book) => {
return book.id !== item.id;
});
},
},
};
</script>
<style scoped>
/* 添加scoped,不会和其他组件发生样式冲突 */
.purchase {
margin: auto;
}
table {
border-color: #ccc;
}
table td,
th {
padding: 10px 20px;
}
table th {
background-color: #ddd;
}
.header {
font-size: 20px;
font-weight: bold;
text-align: center;
}
</style>
原文地址:https://blog.csdn.net/dongxiaod1/article/details/136145245
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!