Vue3电商项目实战-购物车模块2【04-头部购物车-商品列表-本地、05-头部购物车-删除操作-本地、06-购物车页面-基础布局】

news2024/12/23 23:56:28

文章目录

    • 04-头部购物车-商品列表-本地
    • 05-头部购物车-删除操作-本地
    • 06-购物车页面-基础布局


04-头部购物车-商品列表-本地

目的:根据本地存储的商品获取最新的库存价格和有效状态。

大致步骤:

  • 定义获取最新信息的API
  • 定义修改购物车商品信息的mutations
  • 定义获取购物车列表信息的actions
  • 在头部购物车组件初始化的时候更新列表信息

落的代码:

  • 定义获取最新信息的API src/api/cart.js
import request from '@/utils/request'

/**
 * 获取新的商品信息
 * @param {String} skuId - 商品SKUID
 * @returns Promise
 */
export const getNewCartGoods = (skuId) => {
  return request(`/goods/stock/${skuId}`, 'get')
}
定义修改购物车商品信息的mutations src/store/module/cart.js
     // 修改购物车商品
    updateCart (state, goods) {
      // goods中字段有可能不完整,goods有的信息才去修改。
      // 1. goods中必需又skuId,才能找到对应的商品信息
      const updateGoods = state.list.find(item => item.skuId === goods.skuId)
      for (const key in goods) {
        if (goods[key] !== null && goods[key] !== undefined && goods[key] !== '') {
          updateGoods[key] = goods[key]
        }
      }
    }
  • 定义获取购物车列表信息的actions src/store/module/cart.js
    // 获取购物车列表
    findCartList (ctx) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 登录 TODO
        } else {
          // 本地
          // Promise.all() 可以并列发送多个请求,等所有请求成功,调用then
          // Promise.race() 可以并列发送多个请求,等最快的请求成功,调用then
          // 传参事promise数组
          const promiseArr = ctx.state.list.map(item => {
            // 返回接口函数的调用
            return getNewCartGoods(item.skuId)
          })
          Promise.all(promiseArr).then(dataArr => {
            dataArr.forEach((data, i) => {
              ctx.commit('updateCart', { skuId: ctx.state.list[i].skuId, ...data.result })
            })
            resolve()
          }).catch(e => {
            reject(e)
          })
        }
      })
    },
  • 再头部购物车组件初始化的时候更新列表信息 src/components/app-header-cart.vue
  setup () {
    const store = useStore()
    store.dispatch('cart/findCartList')
  }

05-头部购物车-删除操作-本地

目的:完成头部购物车删除操作,支持未登录状态。

大致步骤:

  • 编写mutaions删除购物车商品逻辑
  • 编写actions进行删除操作
  • 在头部购物车进行删除逻辑

落的代码:

  • vuex的mutations和actions代码 src/store/module/cart.js
  mutations: {
    // ... 省略
    // 删除购物车商品
    deleteCart (state, skuId) {
      const index = state.list.findIndex(item => item.skuId === skuId)
      state.list.splice(index, 1)
    }
  },
  actions: {
    // ... 省略
    // 删除购物车商品
    deleteCart (ctx, skuId) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 登录 TODO
        } else {
          // 本地
          ctx.commit('deleteCart', skuId)
          resolve()
        }
      })
    },
  • 头部组件实现删除逻辑 src/components/app-header-cart.vue
+ 购物车无商品不显示弹出层,并且不是在购物车页面
+<div class="layer" v-if="$store.getters['cart/validTotal']&&$route.path!=='/cart'">
+ 绑定点击事件传入skuId
+<i @click="deleteCart(item.skuId)" class="iconfont icon-close-new"></i>
  setup () {
    // 删除
    const deleteCart = (skuId) => {
      store.dispatch('cart/deleteCart', skuId).then(() => {
        Message({ type: 'success', text: '删除成功' })
      }).catch(e => {
        Message({ type: 'error', text: '删除失败' })
      })
    }
    return { deleteCart }
  }

06-购物车页面-基础布局

目的:完成购物车组件基础布局和路由配置与跳转链接。

在这里插入图片描述

大致步骤:

  • 完成头部组件,购物车图标,购物车结算按钮,点击跳转购物车路由。商品点击跳转详情的操作。
  • 配置购物车路由和组件,完成基础布局。

落的代码:

  • 跳转功能 src/components/app-header-cart.vue
    <RouterLink to="/cart" class="curr">
+      <i class="iconfont icon-cart"></i><em>{{$store.getters['cart/validTotal']}}</em>
    </RouterLink>
        <div class="item" v-for="item in $store.getters['cart/validList']" :key="item.skuId">
+          <RouterLink :to="`/product/${item.id}`">
            <img :src="item.picture" alt="">
  <XtxButton type="plain" @click="$router.push('/cart')">去购物车结算</XtxButton>
  • 组件与路由 src/views/cart/index.vue
<template>
  <div class="xtx-cart-page">
    <div class="container">
      <XtxBread>
        <XtxBreadItem to="/">首页</XtxBreadItem>
        <XtxBreadItem>购物车</XtxBreadItem>
      </XtxBread>
      <div class="cart">
        <table>
          <thead>
            <tr>
              <th width="120"><XtxCheckbox>全选</XtxCheckbox></th>
              <th width="400">商品信息</th>
              <th width="220">单价</th>
              <th width="180">数量</th>
              <th width="180">小计</th>
              <th width="140">操作</th>
            </tr>
          </thead>
          <!-- 有效商品 -->
          <tbody>
            <tr v-for="i in 3" :key="i">
              <td><XtxCheckbox /></td>
              <td>
                <div class="goods">
                  <RouterLink to="/"><img src="https://yanxuan-item.nosdn.127.net/13ab302f8f2c954d873f03be36f8fb03.png" alt=""></RouterLink>
                  <div>
                    <p class="name ellipsis">和手足干裂说拜拜 ingrams手足皲裂修复霜</p>
                    <!-- 选择规格组件 -->
                  </div>
                </div>
              </td>
              <td class="tc">
                <p>&yen;200.00</p>
                <p>比加入时降价 <span class="red">&yen;20.00</span></p>
              </td>
              <td class="tc">
                <XtxNumbox />
              </td>
              <td class="tc"><p class="f16 red">&yen;200.00</p></td>
              <td class="tc">
                <p><a href="javascript:;">移入收藏夹</a></p>
                <p><a class="green" href="javascript:;">删除</a></p>
                <p><a href="javascript:;">找相似</a></p>
              </td>
            </tr>
          </tbody>
          <!-- 无效商品 -->
          <tbody>
            <tr><td colspan="6"><h3 class="tit">失效商品</h3></td></tr>
            <tr v-for="i in 3" :key="i">
              <td><XtxCheckbox style="color:#eee;" /></td>
              <td>
                <div class="goods">
                  <RouterLink to="/"><img src="https://yanxuan-item.nosdn.127.net/13ab302f8f2c954d873f03be36f8fb03.png" alt=""></RouterLink>
                  <div>
                    <p class="name ellipsis">和手足干裂说拜拜 ingrams手足皲裂修复霜</p>
                    <p class="attr">颜色:粉色 尺寸:14cm 产地:中国</p>
                  </div>
                </div>
              </td>
              <td class="tc"><p>&yen;200.00</p></td>
              <td class="tc">1</td>
              <td class="tc"><p>&yen;200.00</p></td>
              <td class="tc">
                <p><a class="green" href="javascript:;">删除</a></p>
                <p><a href="javascript:;">找相似</a></p>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      <!-- 操作栏 -->
      <div class="action">
        <div class="batch">
          <XtxCheckbox>全选</XtxCheckbox>
          <a href="javascript:;">删除商品</a>
          <a href="javascript:;">移入收藏夹</a>
          <a href="javascript:;">清空失效商品</a>
        </div>
        <div class="total">
          共 7 件商品,已选择 2 件,商品合计:
          <span class="red">¥400</span>
          <XtxButton type="primary">下单结算</XtxButton>
        </div>
      </div>
      <!-- 猜你喜欢 -->
      <GoodRelevant />
    </div>
  </div>
</template>
<script>
import GoodRelevant from '@/views/goods/components/goods-relevant'
export default {
  name: 'XtxCartPage',
  components: { GoodRelevant }
}
</script>
<style scoped lang="less">
.tc {
  text-align: center;
  .xtx-numbox {
    margin: 0 auto;
    width: 120px;
  }
}
.red {
  color: @priceColor;
}
.green {
  color: @xtxColor
}
.f16 {
  font-size: 16px;
}
.goods {
  display: flex;
  align-items: center;
  img {
    width: 100px;
    height: 100px;
  }
  > div {
    width: 280px;
    font-size: 16px;
    padding-left: 10px;
    .attr {
      font-size: 14px;
      color: #999;
    }
  }
}
.action {
  display: flex;
  background: #fff;
  margin-top: 20px;
  height: 80px;
  align-items: center;
  font-size: 16px;
  justify-content: space-between;
  padding: 0 30px;
  .xtx-checkbox {
    color: #999;
  }
  .batch {
    a {
      margin-left: 20px;
    }
  }
  .red {
    font-size: 18px;
    margin-right: 20px;
    font-weight: bold;
  }
}
.tit {
  color: #666;
  font-size: 16px;
  font-weight: normal;
  line-height: 50px;
}
.xtx-cart-page {
  .cart {
    background: #fff;
    color: #666;
    table {
      border-spacing: 0;
      border-collapse: collapse;
      line-height: 24px;
      th,td{
        padding: 10px;
        border-bottom: 1px solid #f5f5f5;
        &:first-child {
          text-align: left;
          padding-left: 30px;
          color: #999;
        }
      }
      th {
        font-size: 16px;
        font-weight: normal;
        line-height: 50px;
      }
    }
  }
}
</style>

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

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

相关文章

Mybatis工作原理及流程

1、MyBatis介绍 MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来配置和映射原始类型、接口和JavaPOJO(PlainOldJavaObjects,普通老式Java对象)为…

OSSFs挂载工具简介

OSSFs挂载工具 OSSFs挂载工具简介 ​ ossfs允许您在Linux系统中将对象存储OSS的存储空间&#xff08;Bucket&#xff09;挂载到本地文件系统。挂载完成后&#xff0c;您能够像操作本地文件一样操作OSS的对象&#xff08;Object&#xff09;&#xff0c;从而实现数据共享。 ​…

RT_Thread Nano 简介, 移植

官网介绍 RT_Thread Nano 1.简介 RT-Thread Nano 是一个极简版的硬实时内核&#xff0c;它是由 C 语言开发&#xff0c;采用面向对象的编程思维&#xff0c;具有良好的代码风格&#xff0c;是一款可裁剪的、抢占式实时多任务的 RTOS。其内存资源占用极小&#xff0c;功能包括…

打怪升级之MFC变量小实验

按惯例&#xff0c;这一篇文章主要还是作者读《深入浅出MFC》整理的一些笔记。不过本次还加上了一些作者自己的理解。 实验的前期准备 做实验前&#xff0c;你最好了解一下MFC的执行流程&#xff0c;从winapp到各类控件的实际变化过程&#xff0c;可以参考博主之前的笔记。 …

SOTA!目标检测开源框架YOLOv6 3.0版本来啦

近日&#xff0c;美团视觉智能部发布了 YOLOv6 3.0 版本&#xff0c;再一次将目标检测的综合性能推向新高。YOLOv6-L6 检测精度和速度超越 YOLOv7-E6E&#xff0c;取得当前实时目标检测榜单 SOTA。本文主要介绍了 YOLOv6 3.0 版本中引入的技术创新和优化&#xff0c;希望能为从…

64. 最小路径和

64. 最小路径和 给定一个包含非负整数的 m∗nm * nm∗n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 示例 1&#xff1a; 输入&#xff1a;grid [[1,3,1],[1,5,1],[…

Hudi的7种索引

1、Bloom Index Bloom Index (default) 使用根据记录键构建的bloom过滤器&#xff0c;也可以使用记录键范围修剪候选文件.原理为计算RecordKey的hash值然后将其存储到bitmap中&#xff0c;为避免hash冲突一般选择计算3次 HoodieKey 主键信息&#xff1a;主要包含recordKey 和p…

[ IFRS 17 ] 新准则下如何确认保险合同

本系列文章&#xff1a;[ IFRS 17 ] 针对保险新准则 IFRS 17 进行一些列文章更新。如若文中如有所疑问或者不同见解&#xff0c;欢迎留言互动交流。 注&#xff1a;本系列文章受众群体较小众&#xff0c;如若对你感到不适&#xff0c;请立刻点击右上角的 【】 本系列文章适用…

RDD持久化原理和共享变量

&#xff08;一&#xff09; RDD持久化原理 Spark中有一个非常重要的功能就是可以对RDD进行持久化。当对RDD执行持久化操作时&#xff0c;每个节点都会将自己操作的RDD的partition数据持久化到内存中&#xff0c;并且在之后对该RDD的反复使用中&#xff0c;直接使用内存中缓存…

互联网工程师 1480 道 Java 面试题及答案整理 ( 2023 年 整理版)

最近很多粉丝朋友私信我说&#xff1a;熬过了去年的寒冬却没熬过现在的内卷&#xff1b;打开 Boss 直拒一排已读不回&#xff0c;回的基本都是外包&#xff0c;薪资还给的不高&#xff0c;对技术水平要求也远超从前&#xff1b;感觉 Java 一个初中级岗位有上千人同时竞争&#…

安卓逆向_4 --- 定位关键Smali、monitor使用、log插桩、栈追踪、methodprofiling(方法分析)

1、快速定位关键 smali 代码 1.分析流程 搜索特征字符串 搜索关键api 通过方法名来判断方法的功能 2.快速定位关键代码 反编译 APK 程序&#xff0c;AndroidManifest.xml > 包名/系统版本/组件 程序的主 activity(程序入口界面) 每个…

Allegro如何画半圆形的线操作指导

Allegro如何画半圆形的线操作指导 在用Allegro设计PCB的时候,在某些应用场合会需要画半圆形,如下图 如何画半圆形,具体操作如下 点击Add点击Arc w/Radius

WebRTC QoS方法之Pacer实现

本文将解读WebRTC中Pacer算法的实现。WebRTC有两套Pacer算法&#xff1a;TaskQueuePacedSender、PacedSender。本文仅介绍PacedSender的实现。&#xff08;文章中引用的WebRTC代码基于master&#xff0c;commit&#xff1a;3f412945f05ce1ac372a7dad77d85498d23deaae源码分析&a…

算法练习(八)区域搜索

一、腐烂的橘子 1、题目描述&#xff1a; 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b; 值 1 代表新鲜橘子&#xff1b; 值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的…

从零开始:学习使用 Hugo 构建自己的静态网站

1、什么是 Hugo 1.1、简介 Hugo 是一个由 Go 语言编写的静态网站生成器。它可以帮助用户快速构建高性能的静态网站&#xff0c;特别是博客、文档和个人网站等。与其他静态网站生成器相比&#xff0c;Hugo 的特点是速度快、易于使用、可扩展性强等。Hugo 使用简单的 Markdown …

【项目】游戏-我在万科转生成了一只狗

文章目录学习unity一些基操..位置坐标系父子关系常用工具导入游戏模型资源商店创建地形为地形化妆--纹理绘制脚本组件脚本的生命周期脚本执行顺序标签和图层的作用向量的运算和意义欧拉角和四元数-常用C#预制体-类与对象Debug的使用C#物体属性使用游戏时间使用-C#计时器的设置路…

无需手动编码的XGBoost中的分类特征

无需手动编码的XGBoost中的分类特征 XGBoost 是一种基于梯度提升的基于决策树的集成机器学习算法。 然而&#xff0c;直到最近&#xff0c;它还没有原生支持分类数据。 在将分类特征用于训练或推理之前&#xff0c;必须对其进行手动编码。 在序数类别的情况下&#xff0c;例如…

视觉SLAM十四讲ch4 李群和李代数笔记

视觉SLAM十四讲ch4 李群和李代数视觉SLAM十四讲ch4 李群和李代数李群和李代数基础指数映射与对数映射李代数求导与扰动模型视觉SLAM十四讲ch4 李群和李代数 李群和李代数基础 可以将SO3看成旋转矩阵集合&#xff0c;SE3看成变换矩阵集合 李代数是6个自由度的向量空间…

qsort函数的应用以及模拟实现

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:介绍库函数qsort函数的模拟实现和应用 金句分享: ✨追…

Docker之部署Mysql

通过docker对Mysql进行部署。 如果没有部署过docker&#xff0c;看我之前写的目录拉取镜像运行容器开放端口拉取镜像 前往dockerHub官网地址&#xff0c;搜索mysql。 找到要拉取的镜像版本&#xff0c;在tag下找到版本。 拉取mysql镜像&#xff0c;不指定版本数&#xff0c…