4 购物车

4.1 购物车商品数量控制

Detail\index.vue

            <div class="cartWrap">
<div class="controls">
<input v-model="skuNum" @change="changeSkuNum" autocomplete="off" class="itxt">
<a href="javascript:" class="plus">+</a>
<a href="javascript:" class="mins">-</a>
</div>
<div class="add">
<a href="javascript:">加入购物车</a>
</div>
</div>
    // 商品数量
changeSkuNum(event) {
let value = event.target.value * 1
if(isNaN(value) || value < 1 || value > 999) {
console.log('非法数据')
} else {
this.skuNum = parseInt(value)
}
},

通过* 1的方式判断是否输入为非数字,因为非数字乘1的话会变为undefined

4.2 购物车路由跳转

分析:添加购物车需要两个数据:sku_num和sku_id,服务器返回的数据只是成功或者失败不会返回其他信息。

  • 编写api
// api/cart/addToCart/{ skuId }/{ skuNum }
export const reqAddOrUpdateShopCar = (skuId, skuNum) => {
return requests({
url:`/cart/addToCart/${skuId}/${skuNum}`,
method: 'post'
})
}
  • vuex编写actions
const actions = {
async getDetailInfo(context, skuId) {
let result = await reqGetDetailInfo(skuId);
if(result.code === 200) {
context.commit('GETDETAILINFO', result.data);
}
},
async addOrUpdateShopCar({context}, {skuId, skuNum}) {
let result = await reqAddOrUpdateShopCar(skuId, skuNum)
if(result.code === 200) {
return 'ok';
} else {
return Promise.reject(new Error('fail'));
}
}
}

不需要再写mutations和state仓库了,因为没有返回数据

后面请求头写完uuid后会产生数据

  • 编写路由信息
    {
path: '/addShopCarSuccess',
component: AddCartSuccessrt,
name: 'addShopCarSuccess',
meta: {
showFooter: true
}
}
  • 根据返回的结果进行响应路由跳转
    // 购物车添加
async addShopCar() {
try{
await this.$store.dispatch('addOrUpdateShopCar', {
skuId : this.skuInfo.id,
skuNum : this.skuNum
});
this.$router.push({name: 'addShopCarSuccess'})// 路由跳转
} catch (error) {
alert(error.message)
}
}

4.3 路由传参结合回话存储传递数据

分析:H5新增的两种存储:本地存储(localstorage)会话存储(sessionstorage),这里应该使用sessionstorage,因为vue是单页面应用到网页关闭只有一个会话。可以使用路由query传递skuNum而用sessionstorage存储skuInfosquSaleAttrList

  • 将信息存入sessionstorage

Detail/index.vue

// 购物车添加
async addShopCar() {
try{
await this.$store.dispatch('addOrUpdateShopCar', {
skuId : this.skuInfo.id,
skuNum : this.skuNum
});
// 路由跳转
this.$router.push({name: 'addShopCarSuccess', query:{skuNum: this.skuNum}})
sessionStorage.setItem('skuInfo', JSON.stringify(this.skuInfo))
sessionStorage.setItem('spuSaleAttrList', JSON.stringify(this.spuSaleAttrList)) } catch (error) {
alert(error.message)
} }

4.4 请求头加入uuid判断游客身份

分析:可以在本地存储localstorage设置一个uuid,然后每次请求都携带这个uuid,后端就能通过这个uuid在不登录的情况下判断用户返回相应的数据了。那么首先这个uuid应该存储在store仓库中,然后需要一个接口函数能够判断localstorage中有没有uuid,如果没有则创建有则直接返回仓库,最后也是最重要的一步,应该在请求拦截器中的config参数设置uuid,如此发出的请求就能携带uuid了。

  • 编写uuid生成接口 \utils\uuid_token.js
import { v4 as uuidv4 } from 'uuid';

export const getUUID = () => {
let uuid_token = localStorage.getItem('UUID_TOKEN')
if(uuid_token) {
return uuid_token
}
uuid_token = uuidv4()
localStorage.setItem('UUID_TOKEN', uuid_token)
return uuid_token
}
  • 在vuex仓库中生成uuid \store\detail\index.js
import {getUUID} from '@/utils/uuid_token'
const state = {
detailInfo: {},
uuid_token: getUUID()
}

随便找一个模块仓库放就可以

  • 在请求拦截器中config添加携带仓库中的uuid
import store from '@/store'
// 请求拦截器,在请求发出之前能够检测到,做一些指定的业务
requests.interceptors.request.use((config)=>{
// console.log(store.state.detail.uuid_token)
nprogress.start();
// 参数为config的回调函数
// config为配置对象,包含一个中要的属性headers请求头
if(store.state.detail.uuid_token) {
config.headers.userTempId = store.state.detail.uuid_token
}
return config;
});

userTempId为前后端协商的字段不可修改

再次进入购物车页面,可以看到购物车接口可以返回之前加入购物车的数据了。

注意是购物车页面,添加购物车页面是不返回任何数据的

4.5 更新购物车商品数量

更新的接口和添加的结构是相同的,只是,num为负数表示减少为正数表示添加。

export const reqAddOrUpdateShopCar = (skuId, skuNum) => {
return requests({
url:`/cart/addToCart/${skuId}/${skuNum}`,
method: 'post'
})
}

其他没有特别的点,记得发完请求之后再重新获取下页面参数

          <li class="cart-list-con5">
<a @click="skuNumHandler('minus', cartInfo, -1)" class="mins">-</a>
<input autocomplete="off" type="text" @change="skuNumHandler('change', cartInfo, $event.target.value * 1)" :value="cartInfo.skuNum" minnum="1" class="itxt">
<a @click="skuNumHandler('add', cartInfo, 1)" class="plus">+</a>
</li>
    methods: {
getData() {
this.$store.dispatch('getCarList')
},
async skuNumHandler(type, cartInfo, disNum) {
switch(type) {
case 'add':
disNum = 1;
break;
case 'minus':
disNum = cartInfo.skuNum > 0 ? -1 : 0
break;
default:
disNum = isNaN(disNum) ? 0 : disNum - cartInfo.skuNum
break;
}
console.log(disNum)
await reqAddOrUpdateShopCar(cartInfo.skuId, disNum)
// console.log(result.data)
this.getData()
}
}

4.6 删除购物车商品

没啥特别的,直接上代码了

\api\index.js

// /api/cart/deleteCart/{skuId}
export const reqDeleteCarList = (skuId) => {
return requests({
url: `/cart/deleteCart/${skuId}`,
method: 'delete'
})
}

\store\shopCar\index.js

async deleteCarInfo(context, skuId) {
let result = await reqDeleteCarList(skuId)
if(result.code === 200) {
return 'ok'
} else {
return Promise.reject(new Error('failed'))
}
}

\pages\ShopCar\index.vue

async deleteCarInfo(skuId) {
try {
await this.$store.dispatch('deleteCarInfo', skuId)
this.getData()
}catch (err) {
alert(err.message)
}
}

4.7 购物车商品修改的节流

可以发现在快速修改商品数量的时候会变成负数,因此需要对函数做节流,具体参照之前的随笔:【Vue项目】商品汇前台(二)进度条插件+Vuex模块化仓库+函数的防抖与节流+路由传参 - Tod4 - 博客园

    skuNumHandler: throttle(async function (type, cartInfo, disNum) {
switch (type) {
case 'add':
disNum = 1;
break;
case 'minus':
disNum = cartInfo.skuNum > 1 ? -1 : 0
break;
default:
disNum = (isNaN(disNum) || disNum < 1) ? 1 : parseInt(disNum) - cartInfo.skuNum
break;
}
await reqAddOrUpdateShopCar(cartInfo.skuId, disNum)
// console.log(result.data)
this.getData()
}, 500),

4.8 修改产品是否选中的状态

也没啥特别的

\api\idnex.js

// /api/cart/checkCart/{skuID}/{isChecked}
export const reqCheckCart = (skuID, isChecked) => {
return requests({
url: `/cart/checkCart/${skuID}/${isChecked}`,
method: 'get'
})
}

vuex \store\shopCar\index.js

    async checkCart(context, {skuId, isChecked}) {
let result = await reqCheckCart(skuId, isChecked)
if(result.code === 200) {
return 'ok'
} else {
return Promise.reject(new Error('failed'))
}
}

\pages\shopCar\index.vue

    async changeIsChecked(skuId) {
let isChecked = event.target.checked ? 1 : 0
try {
await this.$store.dispatch('checkCart', {
skuId: skuId,
isChecked: isChecked
})
this.getData()
}catch (err) {
alert(err.message)
}
}

4.9 ☆ 删除所选的商品

分析:接口中没有删除多个商品的,因此需要多次调用之前的按照商品ID单独删除商品的接口,可以在仓库中创建一个action使用上下文context多次调用之前的单独删除的actiondeleteCarInfo,而调用action会返回promise,因此需要对多个promise执行一次Promise.all()才能得到五次的结果。

Promise.all()中的一个promise执行失败,则全部的promise都会失败

  • 编写仓库删除多个商品的action

\store\shopCar\index.js

    deleteAllCheckedCar({dispatch, getters}) {
let promises = []
getters.cartInfoList.cartInfoList.forEach(item => {
if(item.isChecked === 1) {
let promise = dispatch('deleteCarInfo', item.skuId)
promises.push(promise)
}
})
return Promise.all(promises)
},
  • 编写组件的派发action的方法

\pages\ShopCar\index.vue

    async deleteAllCheckedCar() {
try {
await this.$store.dispatch('deleteAllCheckedCar')
this.getData()
}catch (err) {
alert(err.message)
}
},

4.10 修改多个商品的选中状态

与上面差不多,直接贴代码了

\pages\ShopCar\index.vue

    changeAllCheckedCar({dispatch, getters}, isChecked) {
let promises = []
getters.cartInfoList.cartInfoList.forEach(item => {
let promise = dispatch('checkCart', {
skuId: item.skuId,
isChecked: isChecked
})
promises.push(promise)
})
return Promise.all(promises)
}

\store\shopCar\index.js

    async changeAllCheckedCar() {
try{
let isChecked = event.target.checked ? 1 : 0
await this.$store.dispatch('changeAllCheckedCar', isChecked)
this.getData()
}catch (err) {
alert(err.message)
}
}

【Vue项目】尚品汇(六)ShopCar组件开发 购物车模块的更多相关文章

  1. vue大型电商项目尚品汇(前台篇)day01

    学完vue2还是决定先做一个比较经典,也比较大的项目来练练手好一点,vue3的知识不用那么着急,先把vue2用熟练了,vue3随时都能学. 这个项目确实很经典包含了登录注册.购物车电商网站该有的都有, ...

  2. vue大型电商项目尚品汇(前台篇)day05终结篇

    前台部分到此结束,一路走来还挺怀念,今天主要是对整个项目的完成做一个最后的收尾工作,对于功能上的需求没有什么了,主要就是项目上线的一些注意事项. 一.个人中心二级路由 当我们点击查看订单应该跳转到个人 ...

  3. vue大型电商项目尚品汇(后台终结篇)day06 重磅!!!

    自此整个项目前后台,全部搭建完毕. 今天是最后一天,内容很多,而且也比较常用,一个图标类数据可视化,一个后台的权限管理,都是很经典的类型. 一.数据可视化 1.简介 专门的一门学科,有专门研究这个的岗 ...

  4. vue大型电商项目尚品汇(前台篇)day02

    现在正式回归,开始好好做项目了,正好这一个项目也开始慢慢的开始起色了,前面的准备工作都做的差不多了. 而且我现在也开始慢慢了解到了一些项目才开始需要的一些什么东西了,vuex.router这些都是必备 ...

  5. vue大型电商项目尚品汇(前台篇)day04

    这几天一直都在做项目,只是没有上传上来,即将把前台项目完结了.现在开始更新整个前台的部分 一.面包屑处理 1.分类操作 点击三级联动进入搜索产生面包屑,直接取参数中的name即可 点击x怎么干掉这个面 ...

  6. vue大型电商项目尚品汇(前台篇)day05

    紧急更新第二弹,然后就剩下最后一弹,也就是整个前台的项目 一.购物车 1.加入购物车(新知识点) 加入到购物车是需要接口操作的,因为我们需要将用户的加入到购物车的保存到服务器数据库,你的账号后面才会在 ...

  7. vue大型电商项目尚品汇(后台篇)day03

    今天把平台属性的管理基本完成了,后台管理做到现在基本也开始熟悉,确实就是对ElementUI的一个熟练程度. 一.平台属性管理 1.动态展示数据 先把接口弄好,应该在第三级标题选择后进行发请求 静态页 ...

  8. vue大型电商项目尚品汇(后台篇)day01

    开始我们后台篇的内容,前面处理了一些事情,去学校完成授位仪式,由校长授位合影,青春不留遗憾,然后还换了一个电脑,征战了四年的神船终于退役了,各种各样的小毛病是真的烦人. 现在正式开始后台篇的内容,做了 ...

  9. vue大型电商项目尚品汇(后台篇)day05

    今天继续是对后台管理部分的一个操作,但是快要结束了,今天结束,明天会进入一个从Vue以来,另外一个名声显著的东西了,一只耳闻从未见识,而且十分的炫酷 他就是------数据可视化Echarts,迫不及 ...

  10. vue大型电商项目尚品汇(后台篇)day02

    这几天更新有点小慢,逐渐开始回归状态了.尽快把这个后台做完,要开始vue3了 3.添加修改品牌 用到组件 Dialog 对话框,其中visible.sync这个配置是修改他的显示隐藏的,label-w ...

随机推荐

  1. 了解JAVA基本知识以及一下常用的dos命令

    9月5日学习 常用的Dos命令 #盘符切换盘符名称: =>回车​#查看当前目录下的所有文件dir​#切换目录 cd change directorycd .. =>返回上一级目录​#清理屏 ...

  2. oracle vm virtualBox 虚拟机共享磁盘后报错

    不能为虚拟电脑 xxx2打开一个新任务. Locking of attached media failed. A possible reason is that one of the media is ...

  3. CF1408

    CF1408 那个博客搭好遥遥无期. A: 直接做就行了,我没智力还写 \(dp\) . #include<bits/stdc++.h> using namespace std; #def ...

  4. NOIP2019 树的重心

    Description \[\sum_{(u,v)\in E}\Biggl(\sum_{x为S_u重心}x+\sum_{y为S_v重心}y\Biggr) \] \(1\leqslant n\leqsl ...

  5. 【原创】android 7.0 通知报错 java.lang.SecurityException: You need MANAGE_USERS permission to: check if specified user a managed profile outside your profile group

    项目中在后台发送通知,突然某一天测出在Android 7.0上通知发送失败,那么根据提示,我们尝试加了MANAGE_USERS权限,看起来是个系统级别权限,验证后果然无效.接着在搜索后都无果,似乎大家 ...

  6. (6) JavaScript - Math对象与日期对象

    1 认识对象 概念:对象就是一种类型,一种引用类型,而对象则是引用类型的实例.在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,通常它也被称作类. 面向过程思想:只考虑过程 ...

  7. 前端复习之css

    1.css概述 1 1.CSS3概述 2 1.问题 3 1.设置页面中所有的文本颜色为红色 4 2.设置页面中所有div的文本的颜色为蓝色 5 3.将所有的div的文本的颜色改为黄色 6 7 HTML ...

  8. 一分钟教你分清各种光纤跳线接头(SC、ST、FC、LC、MPO)

    一分钟教你分清各种光纤跳线接头(SC.ST.FC.LC.MPO)  市场上常见的光纤跳线有以下几种接头:SC.ST.FC.LC.MPO,相信很多入门者和小编一样,面对各种英文缩写也是我只认识他们,却不 ...

  9. 【MSSQL】AlwaysOn集群增加发布订阅

    在现有AlwaysOn集群增加发布订阅节点 配置 前提 节点1.节点2在AlwaysOn集群,节点3作为集群外节点使用订阅复制集群数据同步 发布对象必须要有主键 步骤 登录节点3配置分发distrib ...

  10. C#开发微信

    C#开发微信门户及应用教程   C#开发微信门户及应用(1)--开始使用微信接口... 6 1.微信账号... 6 2.微信菜单定义... 7 3.接入微信的链接处理... 8 4.使用开发方式创建菜 ...