一、前言

在上篇购物车中,如果用户刷新了当前的页面,底部导航中的数据又会恢复为原来的:

1、解决刷新,购物车上数值不变

                                                          2、在购物车点击加减按钮,数值做出对应变化

二、主要内容

1、实现效果:点击购物车的时候可以查看到购物车的商品信息

2、解决刷新,购物车上数值不变

  (1)新建一个Cart.vue展示购物信息,并将路由添加到index.js中

  (2)购物车里面涉及到:存储商品信息,获取商品信息,保存商品信息,这里将这些方法单独封装到一个.js文件中(本来需要在后台操作)

let obj={}; //定义一个对象,存储商品信息

//这里需要存储数据
//{商品的id, 商品的数量} //保存商品
obj.saveGoods = function(goodsList){
window.localStorage.setItem('goodsList',JSON.stringify(goodsList))
} //获取商品的值
obj.getGoodsList = function(){
return JSON.parse(window.localStorage.getItem('goodsList'|| '{}'))//如果stroge中没有值,返回一个空对象
} //增加商品
obj.add = function(goods){
let goodsList = this.getGoodsList()//获取到storage里面的对象
if(goodsList[goods.id]){ //goods.id是商品的数量,对应有值的话就追加
goodsList[goods.id] = goodsList[goods.id] + goods.num;
}else{
goodsList[goods.id]=goods.num;
} //传进来之后还需要保存
this.saveGoods(goodsList);
} //获取购物车的总数量
obj.getTotalCount = function(){
let goodsList = this.getGoodsList();
let values = Object.values(goodsList);//Object.values返回的是一个数组,里面对应着每一个key的value
let sum = 0;
values.forEach(val => sum = sum +val);
return sum; } export default obj;

  (2)封装好了方法就要在商品详情页面使用(类似于我们在淘宝上买东西,当你在商品详情页面点击加入购物车之后,购物车里面会有对应的商品)

 name:'GoodsDetail',
data(){
return{
url:`getthumImages/${this.$route.params.id}`,
goodsInfo:{},//当前购物车的信息,里面有id
pickNum:1 ,
isExist:false //让小球默认是隐藏的状态,
}
},
methods:{
afterEnter(){
this.isExist=false; //显示出来之后执行这个,又将小球隐藏
this.$bus.$emit('sendPickNum',this.pickNum); //当触发了上面的事件之后,
GoodsTool.add({
id:this.goodsInfo.id,
num:this.pickNum
})
},
//点击加入购物车执行这个方法,然后让小球显示出来
ballHandler(){
this.isExist=true;
// this.$bus.$emit('sendPickNum',this.pickNum); //将当前的pickNum传过去,但是这个不能加在这里,否者一点击“加入购物车就传
},

  (3)当你一刷新,stroge里面的数据清空,下面的购物车上面的数值又变成0了,所以在下面的底部导航里,让他一开始就获取到当前这个总数

created(){
//当你的组件一创建好了后就挂载这个bus公交车,$on这个事件监听
this.$bus.$on(`sendPickNum`, (data)=>{
this.pickNum=this.pickNum + data; /
}), this.pickNum=GoodsTool.getTotalCount();//直接将这Goods.vue里面传来的数据赋值,
}

  (4)通过以上思路,就能保证刷新页面时,购物车中的数据不发生改变

3、点击底部导航“购物车”,将上面加进的东西和数量展示在页面中,(在购物车点击加减按钮,数值做出对应变化)

  (1)首先发送请求,这里发送请求的时候,需要之后再购物详情页面加入的商品的id, 然后根据对应的id拿到对应的请求数据

  (2)拿到购物详情里面的id

let goodsList = GoodsTool.getGoodsList();//["88":5,"99":4] 第一个数商品id 第二个是商品数量
let ids = Object.key(goodsList).join(',');//Object.key()获取key值 [88,99]

  (3)拿到上面的id之后就可以发请求

created(){
let goodsList = GoodsTool.getGoodsList();//{"88":5,"99":4} 第一个数商品id 第二个是商品数量
let ids = Object.key(goodsList).join(',');//Object.key()获取key值 [88,99]
if(ids){
this.$axios.get(`goods/getshopcarlist${ids}`)
.then(res=>{
this.shopCart=res.data.message; }
})
}

  (4)但是这里的后端数据库里并没有保存加入购物车的数量(如果有可以直接从后端获取),这里手动添加

created(){
let goodsList = GoodsTool.getGoodsList();//{"88":5,"99":4} 第一个数商品id 第二个是商品数量
let ids = Object.key(goodsList).join(',');//Object.key()获取key值 [88,99]
if(ids){
this.$axios.get(`goods/getshopcarlist${ids}`)
.then(res=>{ this.shopCart=res.data.message;//返回的是一个数组
//给数组元素添加属性
for(var i=0; i<this.shopCart.length;i++){
let shop=this.shopCart[i];//获取到当前的对象
let num = goodsList[shop.id];//根据当前对象的id查找到对应的购物车数量 shop.num = num;//给每个对象添加一个num属性,并在视图上渲染,但是会发现视图上的值并没有改变 } }
})
}

  (5)在购物车列表做加减操作,并且将当前的对象传进去

 <li class="p-list" v-for="(shop, index) in shopCart">
<mt-switch></mt-switch>
<img src="">
<div class="pay-calc">
<p>{{shop.title}}</p>
<div class="calc">
<span>¥777</span>
<span @click="substract(shop)">-</span>
<span>{{shop.num}}</span>
<span @click="addNum(shop)">+</span>
<a href="javascript:;">删除</a>
</div>
</div>
</li>
methods:{
addNum(shop){//每次点击都接受到当前的对象
shop.num++; //这里的值虽然加上了,但是,数据并没有响应上去,是因为created是一开始就加载的,后来点击修改了num的值,但是没有 响应视图
console.log(shop)
},
substract(shop){
if(shop.num==1){
return;
} shop.num--; } },

  (6)做完第五步,在测试的时候,发现控制台中打印出来的对象中num改变,但是视图上并没有改变

    原因:vue 中存在一种机制会将shopCart(也就是你请求的数据进行监视)属性进行监视,完成响应式(因为后面的num是我们自己加进去的,没有挂载到数据属性里面,vue就会对这个属性进行监视,监视到数据不是完全挂载到数据属性上的,就无法完成响应操作)

在vue中的源码中会生成 Object.defineProperty(this, 'shopCart', {   set:function(){   //判断shopCart元素是否有属性  })

    解决方法:如果数据不完整挂载的情况在要添加属性,就需要手动通知vue完成响应式,==》双向数据绑定

created(){
let goodsList = GoodsTool.getGoodsList();//{"88":5,"99":4} 第一个数商品id 第二个是商品数量
let ids = Object.key(goodsList).join(',');//Object.key()获取key值 [88,99]
if(ids){
this.$axios.get(`goods/getshopcarlist${ids}`)
.then(res=>{ this.shopCart=res.data.message;//返回的是一个数组
//给数组元素添加属性
for(var i=0; i<this.shopCart.length;i++){
let shop=this.shopCart[i];//获取到当前的对象
let num = goodsList[shop.id];//根据当前对象的id查找到对应的购物车数量 if(num){
shop.num = num; this.$set(shop, 'num', num);//自己给这个数据进行双向数据绑定
this.$set(shop,'isSelected',true);
}
}
})
}

三、总结

踩坑一:自己收动添加的属性,需要用$set()给这个属性绑定

踩坑二:vue 中存在一种机制会将shopCart(也就是你请求的数据进行监视)属性进行监视,完成响应式(因为后面的num是我们自己加进去的,没有挂载到数据属性里面,vue就会对这个属性进行监视,监视到数据不是完全挂载到数据属性上的,就无法完成响应操作)

Vue(小案例_vue+axios仿手机app)_购物车(二模拟淘宝购物车页面,点击加减做出相应变化)的更多相关文章

  1. Vue(小案例_vue+axios仿手机app)_购物车

    一.前言 1.购物车 二.主要内容 1.效果演示如下,当我们选择商品数量改变的时候,也要让购物车里面的数据改变 2.具体实现 (1)小球从上面跳到下面的效果 (2)当点击上面的“加入购物车按钮”让小球 ...

  2. Vue(小案例_vue+axios仿手机app)_实现用户评论

    一.前言 1.渲染评论列表 2.点击加载按钮,加载更多    3.提交评论 二.主要内容 1.评论列表一般是注册到一个全局的公共组件中 2.请求后台数据,渲染评论列表 (1)数据格式如下 地址 /ap ...

  3. Vue(小案例_vue+axios仿手机app)_公共组件(路由组件传参)

    一.前言                    1.公共轮播图的实现                    2.组件传参,公共组件的实现 二.主要内容 1.公共轮播图的实现 (1)分析:当渲染不同的轮 ...

  4. Vue(小案例_vue+axios仿手机app)_上拉加载

    ---恢复内容开始--- 一.前言                                                                                    ...

  5. Vue(小案例_vue+axios仿手机app)_图片列表操作

    一.前言 1.让图片还没有被完全加载出来的时候给用户提示                                       2.图片查看器 二.主要内容 1.让图片还没有被完全加载出来的时候 ...

  6. Vue(小案例_vue+axios仿手机app)_首页(底部导航栏+轮播图+九宫格)

    ---恢复内容开始--- 一.前言                        1.底部导航(两种做法)                                         2.轮播图 ...

  7. Vue(小案例_vue+axios仿手机app)_图文列表实现

    一.前言 1.导航滑动实现   2.渲染列表信息时让一开始加载的时候就请求数据 3.根据路由的改变,加载图文的改变(实现用户访问网站时可能执行的三个操作) 二.主要内容 1.导航滑动实现: (1)演示 ...

  8. Vue(小案例_vue+axios仿手机app)_购物车(计算商品总金额)

    一.前言                 1.计算总金额                 2.点击删除按钮,删除对应的商品信息                 3.当还没结算的时候,当用户跳到其他页面 ...

  9. Vue(小案例_vue+axios仿手机app)_Vuex优化购物车功能

    一.前言         1.用vuex实现加入购物车操作 2.购物车详情页面          3.点击删除按钮,删除购物详情页面里的对应商品 二.主要内容 1.用vuex加入购物车 (1)在src ...

随机推荐

  1. Spring笔记

    Spring概念 Spring是一个开源的轻量级的框架 Spring核心主要两部分 (1) Aop面向切面编程,扩展功能不是修改源代码实现 (2) Ioc控制反转, 比如说有一个类,在类里面有方法(不 ...

  2. DVWA 黑客攻防演练(十二) DOM型 XSS 攻击 DOM Based Cross Site Scripting

    反射型攻击那篇提及到,如何是"数据是否保存在服务器端"来区分,DOM 型 XSS 攻击应该算是 反射型XSS 攻击. DOM 型攻击的特殊之处在于它是利用 JS 的 documen ...

  3. 简单shellcode编写

    0x00 介绍 Shellcode 是指经过精心设计的一串指令,一旦注入正在运行的应用程序中即可运行,常用于栈和基于堆的溢出.术语Shellcode意思指的便是用于启动一个命令Shell的已编写好的可 ...

  4. 删除Widows 启动项中的信息

    1.打开任务管理器切换到启动Tab,在需要删除的项目上点击右键,点击打开文件所在位置,这样就找到了启动项所在磁盘位置,可以根据需要决定是否删除. 2.从注册表中删除在启动中的注册信息. regedit ...

  5. 【spring源码分析】IOC容器初始化(十二)

    前言:在doCreateBean方法中还遗留一个问题没有分析:循环依赖.循环依赖在Spring中是非常重要的一个知识点,因此单独进行分析. 什么是循环依赖 循环依赖就是循环引用,两个或两个以上的bea ...

  6. springboot 2.1.4 源码默认logback-spring.xml

    logback-spring.xml 是由几个文件组成的,整个的一个xml为 <?xml version="1.0" encoding="UTF-8"?& ...

  7. 从输出日志中提取接口的入参和返回做为用例导入到excel中

    1  背景 接口用例已经在项目中的yml文件中编写,但是yml文件不能做为交付文档用,本文对工作中从接口输出日志中提取用例信息,并导入到excel文件中做了总些 2  工具 idea,notepad+ ...

  8. pyqt5在textBrowser添加文本并自动滑动到底

    pyqt5在textBrowser添加文本并自动滑动到底 说明: 1.按下按钮pushButton,把单行文本框lineEdit里的内容循环不断的添加到多行文本展示框textBrowser.2.必须要 ...

  9. 分布式存储ceph——(2)openstack对接ceph存储后端

    ceph对接openstack环境 一.使用rbd方式提供存储如下数据: (1)image:保存glanc中的image: (2)volume存储:保存cinder的volume:保存创建虚拟机时选择 ...

  10. Matrix Completion with Noise

    目录 引 恢复1 核范数与SDP 稳定恢复 Candes E J, Plan Y. Matrix Completion With Noise[J]. arXiv: Information Theory ...