当前位置: 首页 > news >正文

Day46:项目-购物车案例

购物车案例

  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(() => {//reducereturn 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>

相关文章:

Day46:项目-购物车案例

购物车案例 准备工作 首页默认加载&#xff0c;其余页面懒加载 调用defineStore方法构建store 入口main做对应配置&#xff0c;找指南&#xff0c;快速开始&#xff0c;把elementplus引入进来 import { createApp } from "vue"; import { createPinia } from &qu…...

【小沐学CAD】嵌入式UI开发工具:GL Studio

文章目录 1、简介2、软件功能3、应用行业3.1 航空3.2 汽车3.3 防御3.4 工业3.5 电力与能源3.6 医疗3.7 空间3.8 科技 结语 1、简介 https://disti.com/gl-studio/ DiSTI 是 HMI 软件、虚拟驾驶舱、仪表、信息娱乐、集群显示器和嵌入式 UI 解决方案的领先提供商。 而它的GL Stu…...

Python:Tornado框架之获取get和post的传参

一、获取get方式传参 import tornado.ioloop #导入tornado包 import tornado.web class MainHandle(tornado.web.RequestHandler):def get(self,id): #定义请求函数self.write("Hello %s!" %id)apptornado.web.Application([ #定义应用配置函数(r"/…...

JSON和全局异常处理

目录 1️⃣JSON 一、什么是json&#xff1f; 二、与javascript的关系 三、语法格式 四、注意事项 五、总结 六&#xff0c;使用json 1导入pom.xml依赖 2.配置spring-mvc.xml 3. ResponseBody注解使用 创建一个web层控制器 编写ClazzBiz 实现接口 测试&#xff1a; …...

骨传导耳机有害处吗、骨传导耳机真的不好用吗?

骨传导耳机没有害处。 骨传导耳机是通过将声音传递到颅骨&#xff0c;再由颅骨传递到内耳&#xff0c;从而达到听声音的效果&#xff0c;与传统的耳机不同。 因此&#xff0c;骨传导耳机不会直接对人的身体健康、耳朵产生压力和损伤&#xff0c;也不会影响耳道和中耳的正常功能…...

第一类曲面积分:曲面微元dσ与其投影面积微元dxdy之间的关系推导

第一类曲面积分&#xff1a;曲面微元dσ与其投影面积微元dxdy之间的关系推导 本篇博客精简自本人关于曲面积分的博客&#xff1a;详情见&#xff1a;曲面积分(Surface Integral) 曲面参数化&#xff08;曲面上的每个点都使用起点为原点、终点为该曲面上的点的向量表示&#x…...

vue学习之Font Awesome图标

官方文档 https://fontawesome.com.cn/v5 Font Awesome 安装 cnpm install font-awesome/src/main.js 引入css import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue;...

mysql内连接与外连接详解

内连接与外连接 内连接外连接 在数据库中&#xff0c;连接操作是一种把两个或者多个表的记录组合在一起的操作&#xff0c;常用的有内连接&#xff08;Inner Join&#xff09;、外连接&#xff08;Outer Join&#xff09;等。 内连接 内连接&#xff08;Inner Join&#xff0…...

在Mujoco环境下详细实现PPO算法应用于Humanoid-v2的完整教程

第一部分:介绍 1. 背景介绍 MuJoCo,或称为多关节动力学与控制的物理引擎,已经成为了强化学习中仿真环境的首选工具。其精确的物理仿真和高效的速度使得研究者可以在这个环境下测试和验证各种算法。PPO,即近端策略优化,是一种深度强化学习中的策略优化方法。它解决了TRPO…...

怎么给网络加速

首先&#xff0c;按winr&#xff0c;调出运行窗口。 输入cmd&#xff0c;回车&#xff0c;再输入gpedit.msc&#xff0c;调出本地组策略编辑器。 点击计算机配置下的管理模版。 再点击网络。 再点击Qos数据包计划程序。 再点击限制可保留宽带。 选择已启用&#xff0c;再把带宽…...

golang for循环append的数据重复

原因&#xff0c;因为使用了& 需要增加一行&#xff0c;问题解决...

趣谈网络协议_1

趣谈网络协议_1 第1讲 | 为什么要学习网络协议&#xff1f;第4讲 | DHCP与PXE&#xff1a;IP是怎么来的&#xff0c;又是怎么没的&#xff1f;动态主机配置协议&#xff08;DHCP&#xff09; 第5讲 | 从物理层到MAC层&#xff1a;如何在宿舍里自己组网玩联机游戏&#xff1f;第…...

利用WebStorm开发react——本文来自AI创作助手

要在WebStorm中开发React应用程序&#xff0c;请按照以下步骤进行设置&#xff1a; 1.安装Node.js和npm&#xff08;如果尚未安装&#xff09;。 2.下载和安装WebStorm。 3.打开WebStorm&#xff0c;并在欢迎界面中选择“Create New Project”。 4.在弹出窗口中&#xff0c…...

将本地构建的镜像推送到远程镜像库,构建多种系统架构支持的Docker镜像并推送到Docker Hub

目录 推送到 Docker Hub前提&#xff1a;需要在 [Docker Hub](https://hub.docker.com/) 创建账户、创建仓库。1. 创建 Dockerfile 和构建镜像&#xff1a;docker build -t2. 登录到远程镜像库&#xff1a;docker login3. 将镜像标记为远程仓库地址&#xff1a;docker tag4. 推…...

【技术分享】NetLogon于域内提权漏洞(CVE-2020-1472)

一、漏洞介绍 CVE-2020-1472是一个Windows域控中严重的远程权限提升漏洞。攻击者在通过NetLogon&#xff08;MS-NRPC&#xff09;协议与AD域控建立安全通道时&#xff0c;可利用该漏洞将AD域控的计算机账号密码置为空&#xff0c;从而控制域控服务器。该漏洞适用于Win2008及后…...

python学习之【模块】

前言 上一篇文章 python学习之【深拷贝】中学习了python中的深浅拷贝学习内容&#xff0c;这篇文章接着学习python中的模块。 什么是模块 在python中&#xff0c;一个文件&#xff08;以“.py”为后缀名的文件&#xff09;就叫做一个模块&#xff0c;每一个模块在python里都…...

dns电脑服务器发生故障怎么修复

DNS电脑服务器发生故障可能会导致网络连接问题、网页无法访问、或者电子邮件无法发送等情况。修复DNS电脑服务器故障可以采取多种方法&#xff0c;例如检查网络连接、更换DNS服务器等措施。当DNS电脑服务器发生故障时&#xff0c;可以采取以下修复措施&#xff1a; 尝试刷新DNS…...

Python项目Flask ipv6双栈支持改造

一、背景 Flask 是一个微型的(轻量)使用Python 语言开发的 WSGI Web 框架(一组库和模块),基于Werkzeug WSGI工具箱/库和Jinja2 模板引擎,当然,Python的WEB框架还有:Django、Tornado、Webpy,这暂且不提。 Flask使用BSD授权。 Flask也被称为microframework(微框架),F…...

hcia 目的mac为(单播 组播 广播)mac

从下往上看...

专栏十:10X单细胞的聚类树绘图

经常在文章中看到对细胞群进行聚类,以证明两个cluster之间的相关性,这里总结两种绘制这种图的方式和代码,当然我觉得这些五颜六色的颜色可能是后期加的,本帖子只总结画树状图的方法 例一 文章Single-cell analyses implicate ascites in remodeling the ecosystems of pr…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...