Vue(小案例_vue+axios仿手机app)_购物车(二模拟淘宝购物车页面,点击加减做出相应变化)
一、前言
在上篇购物车中,如果用户刷新了当前的页面,底部导航中的数据又会恢复为原来的:
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)_购物车(二模拟淘宝购物车页面,点击加减做出相应变化)的更多相关文章
- Vue(小案例_vue+axios仿手机app)_购物车
一.前言 1.购物车 二.主要内容 1.效果演示如下,当我们选择商品数量改变的时候,也要让购物车里面的数据改变 2.具体实现 (1)小球从上面跳到下面的效果 (2)当点击上面的“加入购物车按钮”让小球 ...
- Vue(小案例_vue+axios仿手机app)_实现用户评论
一.前言 1.渲染评论列表 2.点击加载按钮,加载更多 3.提交评论 二.主要内容 1.评论列表一般是注册到一个全局的公共组件中 2.请求后台数据,渲染评论列表 (1)数据格式如下 地址 /ap ...
- Vue(小案例_vue+axios仿手机app)_公共组件(路由组件传参)
一.前言 1.公共轮播图的实现 2.组件传参,公共组件的实现 二.主要内容 1.公共轮播图的实现 (1)分析:当渲染不同的轮 ...
- Vue(小案例_vue+axios仿手机app)_上拉加载
---恢复内容开始--- 一.前言 ...
- Vue(小案例_vue+axios仿手机app)_图片列表操作
一.前言 1.让图片还没有被完全加载出来的时候给用户提示 2.图片查看器 二.主要内容 1.让图片还没有被完全加载出来的时候 ...
- Vue(小案例_vue+axios仿手机app)_首页(底部导航栏+轮播图+九宫格)
---恢复内容开始--- 一.前言 1.底部导航(两种做法) 2.轮播图 ...
- Vue(小案例_vue+axios仿手机app)_图文列表实现
一.前言 1.导航滑动实现 2.渲染列表信息时让一开始加载的时候就请求数据 3.根据路由的改变,加载图文的改变(实现用户访问网站时可能执行的三个操作) 二.主要内容 1.导航滑动实现: (1)演示 ...
- Vue(小案例_vue+axios仿手机app)_购物车(计算商品总金额)
一.前言 1.计算总金额 2.点击删除按钮,删除对应的商品信息 3.当还没结算的时候,当用户跳到其他页面 ...
- Vue(小案例_vue+axios仿手机app)_Vuex优化购物车功能
一.前言 1.用vuex实现加入购物车操作 2.购物车详情页面 3.点击删除按钮,删除购物详情页面里的对应商品 二.主要内容 1.用vuex加入购物车 (1)在src ...
随机推荐
- div在另一个div居中对齐
position:fixed; top:0; right:0; left:0; bottom:0; margin:auto;
- java基础(一):谈谈java内存管理与垃圾回收机制
看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...
- 为Jekyll+GitHub Pages添加全文搜索功能
动态演示如下: [上传失败, 请自行搜索原文] 源码库: program-in-chinese/team_website 找到此JS工具: christian-fei/Simple-Jekyll-Se ...
- 华为6.0系统设备最完美激活Xposed框架的经验
对于喜欢玩手机的伙伴而言,经常会使用上Xposed框架及种种功能强大的模块,对于5.0以下的系统版本,只要手机能获得root权限,安装和激活Xposed框架是非常轻松的,但随着系统版本的迭代,5.0以 ...
- APICloud Studio2新建应用报错和检出错误
今天心血来潮,闲暇时间想做个移动应用app,听一哥们说APICloud开发app很方便,就查询了一下,看了之后简直就是热血沸腾,我感觉正是我一直要找的工具 信心满满的开始着手使用,看了一下介绍我选择了 ...
- Linux学习历程——Centos 7 passwd命令
一.命令介绍 passwd 命令用于修改用户密码,过期时间,认证信息等. 普通用户只能使用 passwd 命令修改自身的系统密码,而 root 管理员则有权限修改其他所有人的密码.更酷的是,root ...
- 「插件」Runner更新Pro版,帮助设计师远离996
三年多前Runner团队在德国汉堡的骇客松上第一次发布了Sketch插件Runner的beta版本.从那以后,这个团队的目标一直很清晰: 创造一个加速设计工作流的工具. 他们只给Runner添加真正能 ...
- Running Spark Streaming Jobs on a Kerberos-Enabled Cluster
Use the following steps to run a Spark Streaming job on a Kerberos-enabled cluster. Select or create ...
- springboot 应用中静态资源下载
一. 场景介绍 Excel模板静态资源在,应用中的static文件夹中,文件名称包含中文; 需求:页面直接访问下载Excel模板. 二.目录结构 三.后台代码 @GetMapping("/d ...
- oracle 关于对时间操作的汇总
-- 对时间的操作 对当前日期增加一个小时: SQL> select sysdate, sysdate+numtodsinterval(1,’hour’) from dual ; 对当前日期增加 ...