自学内容网 自学内容网

Vue购物车综合案例

Vue购物车综合案例

1. 演示效果

QQ录屏20240215154248 -original-original

2. 代码分析

image-20240218083810308

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)!