Day46:项目-购物车案例

news2025/2/27 1:43:40

购物车案例

  1. 准备工作
    1. 首页默认加载,其余页面懒加载

    2. 调用defineStore方法构建store

    3. 入口main做对应配置,找指南,快速开始,把elementplus引入进来
import { createApp } from "vue";
import { createPinia } from "pinia";
import "./style.css";
import App from "./App.vue";
import router from "./router";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
const app = createApp(App);
const pinia = createPinia();
app.use(router);
app.use(pinia);
app.use(ElementPlus);
app.mount("#app");
    1. api就是用来模拟后台接口的

  1. 在app.vue中做购物车首页,头部不进入路由,在头部的底部放RouterView
  2. 给app 的header添加插槽#header,写类名添加样式,头部插槽内的内容不会发生变化
<template>
  <div>
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <h1>购物车首页</h1>
          <div class="btn">
            <RouterLink to="/productlist">
              <el-button type="primary">商品列表</el-button></RouterLink
            >
            <RouterLink to="/shoppingcar"
              ><el-button type="primary">购物车</el-button></RouterLink
            >
          </div>
        </div>
      </template>
      <RouterView />
    </el-card>
  </div>
</template>
    1. 写购物车首页的标题
    2. 写el-button:商品列表,购物车。并用routerLink包裹,做一个导航,并为RouterLink添加to页面
  1. 在商品列表页面,写一个el-table,
<template>
    <div class="product-list">
      <el-table :data="shoppingCarStore.productList" stripe style="width: 100%">
        <el-table-column prop="id" label="序号" align="center" />
        <el-table-column prop="title" label="商品名称" align="center" />
        <el-table-column prop="price" label="商品价格" align="center" />
        <el-table-column prop="number" label="库存" align="center" />
        <el-table-column prop="address" label="操作" align="center">
          <template #default="scope">
            <el-button type="success" @click="add(scope.row)">
              添加到购物车
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </template>
  1. 在store中写方法,初始化商品列表和初始化商品数据的方法
import { defineStore } from "pinia";
import { computed, ref } from "vue";
import { getProducts } from "../api/product";
import { ElMessage } from "element-plus";
import { buyProducts } from "../api/product.js";
const useShoppingCarStore = defineStore("shopping-car", () => {
  //初始化商品列表数据
  const productList = ref([]);
  //初始化购物车列表数据
  const shopCarList = ref([]);
    1. 一秒钟之后获取到数据(模拟从接口获取数据),
//1s中之后返回数组数据
export const getProducts = async ()=>{
    //为了模拟真实的接口请求
    await wait(1000)
    return products
}
    1. 方法在数据获取的部分有定义。
    2. 把两个需要给视图使用的方法从store中导出,并在商品列表中导入方法
    3. 绑定在table中,
  1. 给table添加按钮
    1. 改变button样式
    2. 绑定add方法,在页面中传参scope.row,代表点选的那一行。(scope代表插槽的作用域)在方法中传参row
<script setup>
import { useShoppingCarStore } from "../store";
const shoppingCarStore = useShoppingCarStore();
shoppingCarStore.getProductList();
function add(row) {
  //调用 将数据添加到购物车的方法
  shoppingCarStore.addShopCarList(row);
}
</script>
  1. 在store中写给购物车添加数据的方法
    1. 减去商品列表页面的库存:res的item id === row id时,下转判断,判断完自减--
    2. 添加购物车列表页面的商品数量,_res的item id === row id时,下转判断
      1. 在store中定义初始化购物车列表
      2. 判断购物车中是否已经存在这个商品
      3. 如果存在,将商品数量+1(_res.number++
      4. 如果没有,添加一个新商品(起始数量一定是1
    1. 判断当库存<1,写一个提示,商品已经妹有了,存在一秒。
    2. 导出方法并在列表页调用,放在add方法中,add传入的参数为row,指在点选的那一行。
const useShoppingCarStore = defineStore("shopping-car", () => {
  //初始化两行
......
  //初始化商品列表数据的方法(使用async方法,没有一大堆回调函数
  const getProductList = async () => {
    const res = await getProducts();
    productList.value = res;
  };
  // const getProductList = () => {
  //   getProducts().then((res) => {
  //     productList.value = res;
  //   });
  // };
  //给购物车添加数据的方法
  const addShopCarList = (row) => {
    //1. 减去商品列表页面的商品库存
    const res = productList.value.find((item) => item.id === row.id);
    if (res.number < 1) {
      ElMessage.error({
        message: "没有库存辣!",
        duration: 1000,
      });
      return;
    }
    res.number--;
    //2. 添加购物车列表页面的商品数量
    const _res = shopCarList.value.find((item) => item.id === row.id);
    //2.1 判断购物车列表数据中是否包含当前的商品 如果包含 让数量自增
    //2.2 如果不包含 将这个商品添加到购物车列表
    if (!_res) {
      shopCarList.value.push({
        id: row.id,
        title: row.title,
        price: row.price,
        number: 1,
      });
    } else {
      _res.number++;
    }
    //给购物车列表中的商品按照id的升序做一个排序
    shopCarList.value.sort((a, b) => {
      return a.id - b.id;
    });
  };
...
  return{...addShopCarList,...};
  1. 在购物车列表中写el-table
    1. 引入useshoppingcarstore,并绑定数据.shopCarList
    2. 绑定prop属性,表示绑定了哪个属性
  1. 在store中添加排序功能,商品加入购物车后按照id自动排序,写在_res判断下面
    1. shopCarList.value.sort((a,b) => {})

getProductsList方法最好使用async和await语法,而不是等价的.then。因为async和await语法不涉及大量的回调函数,也就不用进行大量的回调函数嵌套,处理起来更简单不容易出错。

//初始化商品列表数据的方法
  const getProductList = async () => {
    const res = await getProducts();
    productList.value = res;
  };
  // const getProductList = () => {
  //   getProducts().then((res) => {
  //     productList.value = res;
  //   });
  // };
  1. 写普通的table计算shopCarList里的商品总价
    1. 使用computed计算属性计算商品总价。
    2. const一个totalPrice
const useShoppingCarStore = defineStore("shopping-car", () => {
  //初始化商品列表数据
......
  //计算shopcarList里的商品总价
  const totalPrice = computed(() => {
    //reduce
    return shopCarList.value.reduce((pre, cur) => {
      return pre + cur.number * cur.price;
    }, 0);
  });
  .....
  return {...totalPrice,...};
});
    1. return一个reduce方法,它是一个数组遍历中常用的方法。第一个参数为回调逻辑,第二个参数为累加初始值(大多数为0)

    2. 把商品总价渲染到页面
  1. 在商品列表页写一个结算商品的button,
    1. 绑定点击事件calc(vue2不能直接绑click,需要加字符;vue3的组件绑定会判断是否为原生事件)
    2. 在store中写calc方法
    3. 结算方法已经写在products中,引入到store中。
    4. 该方法通过一个随机数来随机判断结算是否成功。、
    5. 这是一个异步方法,需要async和await
    6. 判断结算是否成功,成功弹出成功,并清空数组;
    7. 结算失败弹出失败,不清空列表,需要再次结算。
const useShoppingCarStore = defineStore("shopping-car", () => {
 ......
  //结算商品列表的方法
  const calc = async () => {
    const res = await buyProducts();
    if (res) {
      ElMessage.success({
        message: "结算成功",
        duration: 1000,
      });
      shopCarList.value = [];
    } else {
      ElMessage.error({
        message: "结算失败",
        duration: 1000,
      });
    }
  };
  return {
    ....
    calc,
  };
});
  1. 购物车中,对结算框v-if判断,如果购物车列表没有数据,则不显示结算框。
<template>
  <div class="shopping-car">
    <el-table :data="shoppingCarStore.shopCarList">
      <el-table-column prop="id" label="序号" align="center" />
      <el-table-column prop="title" label="名称" align="center" />
      <el-table-column prop="price" label="价格" align="center" />
      <el-table-column prop="number" label="数量" align="center" />
    </el-table>
    <div class="btn" v-if="shoppingCarStore.shopCarList.length">
      <h2>商品总价是:{{ shoppingCarStore.totalPrice }}</h2>
      <el-button type="primary" @click="calc">结算商品</el-button>
    </div>
  </div>
</template>

<script setup>
import { useShoppingCarStore } from "../store";
const shoppingCarStore = useShoppingCarStore();
function calc() {
  //触发商品结算的方法 calc()
  shoppingCarStore.calc();
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1016442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于香橙派和SU-03T 使用Linux实现语音控制刷抖音

硬件介绍 SU-03T之前在小车的时候使用过&#xff0c;详见&#xff1a;语音小车---6 最终整合_mjmmm的博客-CSDN博客 按照下图进行接线&#xff1a; 项目需求 通过语音指令来控制安卓手机刷抖音&#xff0c;可以实现视频切换和点赞等功能&#xff1a; 1. 开机播报“你好&a…

产品经理-战略-战略的含义和层级

引言 22年老板在听我做部门人员数量汇报时&#xff0c;当场就给我们部门员工做能力标签&#xff0c;过了几天就输出了一个公司所有技术岗位的能力标签。其中有一项是战略思维&#xff0c;该项满分是5分&#xff0c;我们部门同事绝大部分人都只有2分&#xff0c;我自己也就3…

数据结构-leetcode-环形链表Ⅱ

有了上一篇的基础&#xff0c;做这一篇会相对容易些&#xff0c;没看上一篇的一定要去看看再来。 先看题&#xff1a; 解题图解&#xff1a; 1.首先要使快慢指针相遇 2. 代码如下&#xff1a; struct ListNode *detectCycle(struct ListNode *head) {struct ListNode * fasthe…

IF,AND,OR 或嵌套 IF 在 Excel 中不是逻辑函数

事情并非总是我们希望的那样。 意外的事情可能发生。 例如&#xff0c;假设您必须将数字相除。 尝试将任何数字除以零&#xff08;0&#xff09;都会产生错误。 在这种情况下&#xff0c;逻辑功能很方便。 在本教程中&#xff0c;我们将涵盖以下主题。 在本教程中&#xff0c;…

企业架构LNMP学习笔记53

PHP扩展安装&#xff1a; server01和server03上安装redis扩展&#xff1a; 解压编译安装&#xff1a; shell > tar xvf redis-4.3.0.tgz shell > cd redis-4.3.0 shell > phpize shell > ./configure && make && make install 配置文件php.ini&…

JVM——3.StringTable字符串常量池

这篇文章我们来讲一下StringTable字符串常量池 目录 1.引例 2.StringTable的特性 3.StringTable的位置 4.StringTable的垃圾回收、 5.StringTable性能调优 6.总结 1.引例 首先&#xff0c;我们来看下面的这段程序&#xff0c;请思考最终的输出结果。 输出结果&#xff…

网络安全(黑客)自学​

前言 作为一个合格的网络安全工程师&#xff0c;应该做到攻守兼备&#xff0c;毕竟知己知彼&#xff0c;才能百战百胜。 计算机各领域的知识水平决定你渗透水平的上限。 【1】比如&#xff1a;你编程水平高&#xff0c;那你在代码审计的时候就会比别人强&#xff0c;写出的漏洞…

北大C++课后记录:文件读写的I/O流

前言 文件和平常用到的cin、cout流其实是一回事&#xff0c;可以将文件看作一个有限字符构成的顺序字符流&#xff0c;基于此&#xff0c;也可以像cin、cout读键盘数据那样对文件进行读写。 读写指针 输入流的read指针 输出流的write指针 注&#xff1a;这里的指针并不是普…

Type-C座子ESD整改案例分析?|深圳比创达EMC

Type-C座子ESD整改案例分析&#xff1f;相信不少人是有疑问的&#xff0c;今天深圳市比创达电子科技有限公司就跟大家解答一下&#xff01; 近年来&#xff0c;Type-C座子是一个应用非常广泛的一款通讯端口&#xff0c;具有正反可插、更快的充电和数据传输、音频转换、接口转换…

摩托车题目 记录

1 《道路安全法实施条例》第五十五条第三例:摩托车后座不得乘坐未满12周岁的未成年人&#xff0c;轻便摩托车不得载人。 所以本题选择【错误】。 《道路交通安全法实施条例》第六十二条:驾驶机动车不得有下列行为:(六)驾驶摩托车手离车把或者在车把上悬挂物品。所以&#xff0…

LeetCode2.两数相加

一看完题&#xff0c;我的想法是先算出这两个链表表示的数&#xff0c;然后相加&#xff0c;然后把这个数一位一位的分配给第三个数组&#xff0c;这种方法应该很简单但是要遍历三次数组&#xff0c;于是我就想直接一遍遍历&#xff0c;两个链表同时往后面遍历&#xff0c;把这…

【Unity 实用工具篇】✨ | 编辑器扩展插件 Odin Inspector,快速上手学习

前言【Unity 实用工具篇】✨ | 编辑器扩展插件 Odin Inspector,快速上手学习一、Odin Inspector插件1.1 介绍1.2 相关网站链接1.3 效果展示二、导入插件三、基础功能介绍四、快速上手4.1 Attributes 相关4.1.1 使用Attribute更好的显示数据。Title、BoxGroup、FoldoutGroup4.1…

ruoyi权限设置的坑

如果是手动在页面加了菜单&#xff0c;其实会生成一条数据&#xff0c;也就是2001这条已经有了。 所以生成的SQL就会有重的&#xff0c;这一点要注意。 可以不手动创建菜单&#xff0c;直接使用SQL&#xff0c;或者就改SQL了。 手动页面创建的菜单&#xff0c;一个定要注意&…

Haproxy搭建 Web 群集实现负载均衡

目录 1 Haproxy 1.1 HAProxy的主要特性 1.2 HAProxy负载均衡策略 1.3 LVS、Nginx、HAproxy的区别 2 Haproxy搭建 Web 群集 2.1 haproxy 服务器部署 2.1.1 关闭防火墙 2.1.2 内核配置&#xff08;实验环境可有可无&#xff09; ​2.1.3 安装 Haproxy 2.1.4 Haproxy服务…

数额结构(6.1~6.8)

6-1链表的插入算法 题目&#xff1a; 代码 int InsertPost_link(LinkList llist,DataType x,DataType y) {LinkList mllist->next;LinkList n;while(m->data!x){mm->next;4if(mNULL){printf("not exist data %d\n",x);return 0;}}n(LinkList)malloc(si…

Navicat工具连接Oracle数据库

文章目录 准备工具NavicatNavicat的Oracle插件Oracle查看系统版本找到对应的工具版本下载 oci下载 sqlplus 步骤1.打开navicat&#xff0c;工具>选项>环境2.配置3.点击确定&#xff0c;并重启navicat4.创建oracle连接 准备工具 工欲善其事&#xff0c;必先利其器&#x…

《Python趣味工具》——自制emoji2(2)

今天&#xff0c;我们将会完成以下2个内容&#xff1a; 绘制静态emoji总结turtle中常用的绘图函数 文章目录 一、绘制静态emoji&#xff1a;:sparkles: 画脸&#xff1a;:sparkles:绘制嘴巴&#xff1a;:sparkles:绘制眼白&#xff1a;绘制眼白-Part1&#xff1a;绘制眼白—pa…

算法之排序

文章目录 前言一、二分查找1、正常二分2、二分找第一个出现要查找的数的位置3、在旋转数组中找最小数字二分总结 一、归并排序1、正常归并2、小和问题归并总结 前言 之前我们学习了各种排序算法&#xff0c;今天来让我们看看在线OJ上的题目吧&#xff0c;有哪些排序算法有什么…

数据结构之美:如何优化内存和性能

文章目录 什么是数据结构&#xff1f;内存优化使用紧凑的数据类型避免冗余存储使用位运算压缩数据 性能优化使用适当的数据结构减少不必要的复制使用合适的算法 数据结构优化的案例分析结论 &#x1f389;欢迎来到数据结构学习专栏~探索数据结构之美&#xff1a;如何优化内存和…

滑动窗口 解题思路

文章目录 算法应用场景滑动窗口解题思路1. 寻找最长2. 寻找最短 算法应用场景 关键词&#xff1a; 满足 xxx 条件 &#xff08;计算结果&#xff0c;出现次数&#xff0c;同时包含&#xff09; 最长 / 最短 子串 / 子数组 / 子序列 例如&#xff1a;长度最短的子串 滑动窗口…