商城-购物车-未登录购物车
3.未登录购物车
3.1.准备
3.1.1购物车的数据结构
首先分析一下未登录购物车的数据结构。
我们看下页面展示需要什么数据:
因此每一个购物车信息,都是一个对象,包含:
{
skuId:2131241,
title:"小米6",
image:"",
price:190000,
num:1,
ownSpec:"{"机身颜色":"陶瓷黑尊享版","内存":"6GB","机身存储":"128GB"}"
}
另外,购物车中不止一条数据,因此最终会是对象的数组。即:
[
{...},{...},{...}
]
3.1.2.web本地存储
知道了数据结构,下一个问题,就是如何保存购物车数据。前面我们分析过,可以使用Localstorage来实现。Localstorage是web本地存储的一种,那么,什么是web本地存储呢?
什么是web本地存储?
web本地存储主要有两种方式:
- LocalStorage:localStorage 方法存储的数据没有时间限制。第二天、第二周或下一年之后,数据依然可用。
- SessionStorage:sessionStorage 方法针对一个 session 进行数据存储。当用户关闭浏览器窗口后,数据会被删除。
LocalStorage的用法
语法非常简单:
localStorage.setItem("key","value"); // 存储数据
localStorage.getItem("key"); // 获取数据
localStorage.removeItem("key"); // 删除数据
注意:localStorage和SessionStorage都只能保存字符串。
不过,在我们的common.js中,已经对localStorage进行了简单的封装:
示例:
3.1.3.获取num
添加购物车需要知道购物的数量,所以我们需要获取数量大小。我们在Vue中定义num,保存数量:
然后将num与页面的input框绑定,同时给+
和-
的按钮绑定事件:
编写方法:
3.2.添加购物车
3.2.1.点击事件
我们看下商品详情页:
现在点击加入购物车会跳转到购物车成功页面。
不过我们不这么做,我们绑定点击事件,然后实现添加购物车功能。
addCart方法中判断用户的登录状态:
addCart(){
ly.http.get("/auth/verify").then(res=>{
// 已登录发送信息到后台,保存到redis中
}).catch(()=>{
// 未登录保存在浏览器本地的localStorage中
})
}
3.2.2.获取数量,添加购物车
addCart(){
ly.verifyUser().then(res=>{
// 已登录发送信息到后台,保存到redis中
}).catch(()=>{
// 未登录保存在浏览器本地的localStorage中
// 1、查询本地购物车
let carts = ly.store.get("carts") || [];
let cart = carts.find(c=>c.skuId===this.sku.id);
// 2、判断是否存在
if (cart) {
// 3、存在更新数量
cart.num += this.num;
} else {
// 4、不存在,新增
cart = {
skuId: this.sku.id,
title: this.sku.title,
price: this.sku.price,
image: this.sku.images,
num: this.num,
ownSpec: JSON.stringify(this.ownSpec)
}
carts.push(cart);
}
// 把carts写回localstorage
ly.store.set("carts", carts);
// 跳转
window.location.href = "http://www.leyou.com/cart.html";
});
}
结果:
添加完成后,页面会跳转到购物车结算页面:cart.html
3.3.查询购物车
3.3.1.校验用户登录
因为会多次校验用户登录状态,因此我们封装一个校验的方法:
在common.js中:
在页面item.html中使用该方法:
3.3.2.查询购物车
页面加载时,就应该去查询购物车。
var cartVm = new Vue({
el: "#cartApp",
data: {
ly,
carts: [],// 购物车数据
},
created() {
this.loadCarts();
},
methods: {
loadCarts() {
// 先判断登录状态
ly.verifyUser().then(() => {
// 已登录
}).catch(() => {
// 未登录
this.carts = ly.store.get("carts") || [];
this.selected = this.carts;
})
}
}
components: {
shortcut: () => import("/js/pages/shortcut.js")
}
})
刷新页面,查看控制台Vue实例:
3.5.2.渲染到页面
接下来,我们在页面中展示carts的数据:
要注意,价格的展示需要进行格式化,这里使用的是我们在common.js中定义的formatPrice方法
效果:
3.6.修改数量
我们给页面的 +
和 -
绑定点击事件,修改num 的值:
两个事件:
increment(c) {
c.num++;
ly.verifyUser().then(() => {
// TODO 已登录,向后台发起请求
}).catch(() => {
// 未登录,直接操作本地数据
ly.store.set("carts", this.carts);
})
},
decrement(c) {
if (c.num <= 1) {
return;
}
c.num--;
ly.verifyUser().then(() => {
// TODO 已登录,向后台发起请求
}).catch(() => {
// 未登录,直接操作本地数据
ly.store.set("carts", this.carts);
})
}
3.7.删除商品
给删除按钮绑定事件:
点击事件中删除商品:
deleteCart(i){
ly.verifyUser().then(res=>{
// TODO,已登录购物车
}).catch(()=>{
// 未登录购物车
this.carts.splice(i, 1);
ly.store.set("carts", this.carts);
})
}
3.8.选中商品
在页面中,每个购物车商品左侧,都有一个复选框,用户可以选择部分商品进行下单,而不一定是全部:
我们定义一个变量,记录所有被选中的商品:
3.8.1.选中一个
我们给商品前面的复选框与selected绑定,并且指定其值为当前购物车商品:
3.8.2.初始化全选
我们在加载完成购物车查询后,初始化全选:
3.8.4.总价格
然后编写一个计算属性,计算出选中商品总价格:
computed: {
totalPrice() {
return ly.formatPrice(this.selected.reduce((c1, c2) => c1 + c2.num * c2.price, 0));
}
}
在页面中展示总价格:
效果: