title: 樂優(yōu)商城學(xué)習(xí)筆記二十五-購物車(一)
date: 2019-04-25 21:11:46
tags:
- 樂優(yōu)商城
- java
- springboot
categories:
- 樂優(yōu)商城
0.學(xué)習(xí)目標(biāo)
1.搭建購物車服務(wù)
1.1.創(chuàng)建module
1.2.pom依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>leyou</artifactId>
<groupId>com.leyou.parent</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.leyou.service</groupId>
<artifactId>ly-cart</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
1.3.配置文件
server:
port: 8088
spring:
application:
name: cart-service
redis:
host: 192.168.56.101
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
registry-fetch-interval-seconds: 5
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
instance-id: ${eureka.instance.ip-address}.${server.port}
lease-renewal-interval-in-seconds: 3
lease-expiration-duration-in-seconds: 10
1.4.啟動類
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class LyCartApplication {
public static void main(String[] args) {
SpringApplication.run(LyCartApplication.class, args);
}
}
2.購物車功能分析
2.1.需求
需求描述:
- 用戶可以在登錄狀態(tài)下將商品添加到購物車
- 放入數(shù)據(jù)庫
- 放入redis(采用)
- 用戶可以在未登錄狀態(tài)下將商品添加到購物車
- 放入localstorage
- 用戶可以使用購物車一起結(jié)算下單
- 用戶可以查詢自己的購物車
- 用戶可以在購物車中可以修改購買商品的數(shù)量蜜另。
- 用戶可以在購物車中刪除商品。
- 在購物車中展示商品優(yōu)惠信息
- 提示購物車商品價格變化
2.2.流程圖:
這幅圖主要描述了兩個功能:新增商品到購物車右蹦、查詢購物車滔以。
新增商品:
- 判斷是否登錄
- 是:則添加商品到后臺Redis中
- 否:則添加商品到本地的Localstorage
無論哪種新增捉腥,完成后都需要查詢購物車列表:
- 判斷是否登錄
- 否:直接查詢localstorage中數(shù)據(jù)并展示
- 是:已登錄,則需要先看本地是否有數(shù)據(jù)你画,
- 有:需要提交到后臺添加到redis抵碟,合并數(shù)據(jù),而后查詢
- 否:直接去后臺查詢redis坏匪,而后返回
3.未登錄購物車
3.1.準(zhǔn)備
3.1.1購物車的數(shù)據(jù)結(jié)構(gòu)
首先分析一下未登錄購物車的數(shù)據(jù)結(jié)構(gòu)拟逮。
我們看下頁面展示需要什么數(shù)據(jù):
因此每一個購物車信息,都是一個對象适滓,包含:
{
skuId:2131241,
title:"小米6",
image:"",
price:190000,
num:1,
ownSpec:"{"機身顏色":"陶瓷黑尊享版","內(nèi)存":"6GB","機身存儲":"128GB"}"
}
另外敦迄,購物車中不止一條數(shù)據(jù),因此最終會是對象的數(shù)組凭迹。即:
[
{...},{...},{...}
]
3.1.2.web本地存儲
知道了數(shù)據(jù)結(jié)構(gòu)罚屋,下一個問題,就是如何保存購物車數(shù)據(jù)嗅绸。前面我們分析過脾猛,可以使用Localstorage來實現(xiàn)。Localstorage是web本地存儲的一種朽砰,那么尖滚,什么是web本地存儲呢?
什么是web本地存儲瞧柔?
web本地存儲主要有兩種方式:
- LocalStorage:localStorage 方法存儲的數(shù)據(jù)沒有時間限制漆弄。第二天、第二周或下一年之后造锅,數(shù)據(jù)依然可用撼唾。
- SessionStorage:sessionStorage 方法針對一個 session 進行數(shù)據(jù)存儲。當(dāng)用戶關(guān)閉瀏覽器窗口后哥蔚,數(shù)據(jù)會被刪除倒谷。
LocalStorage的用法
語法非常簡單:
localStorage.setItem("key","value"); // 存儲數(shù)據(jù)
localStorage.getItem("key"); // 獲取數(shù)據(jù)
localStorage.removeItem("key"); // 刪除數(shù)據(jù)
注意:localStorage和SessionStorage都只能保存字符串蛛蒙。
不過,在我們的common.js中渤愁,已經(jīng)對localStorage進行了簡單的封裝:
示例:
3.1.3.獲取num
添加購物車需要知道購物的數(shù)量牵祟,所以我們需要獲取數(shù)量大小。我們在Vue中定義num抖格,保存數(shù)量:
然后將num與頁面的input框綁定诺苹,同時給+
和-
的按鈕綁定事件:
編寫事件:
3.2.添加購物車
3.2.1.點擊事件
我們看下商品詳情頁:
現(xiàn)在點擊加入購物車會跳轉(zhuǎn)到購物車成功頁面。
不過我們不這么做雹拄,我們綁定點擊事件收奔,然后實現(xiàn)添加購物車功能。
addCart方法中判斷用戶的登錄狀態(tài):
3.2.2.獲取數(shù)量滓玖,添加購物車
addCart(){
// 判斷登錄狀態(tài)
ly.http.get("/auth/verify")
.then(resp => {
})
.catch(() => {
// 未登錄坪哄,添加到localstorage
// 1、查詢本地購物車
const carts = ly.store.get("carts") || [];
let cart = carts.find(c => c.skuId === this.sku.id);
// 2势篡、判斷是否存在
if(cart){
// 3翩肌、存在,改數(shù)量
cart.num += this.num;
}else {
// 4殊霞、不存在摧阅,新增
cart = {
skuId: this.sku.id,
title: this.sku.title,
image: this.images[0],
price: this.sku.price,
num: this.num,
ownSpec: JSON.stringify(this.ownSpec)
};
carts.push(cart);
}
// 把carts寫回localstorage
ly.store.set("carts", carts);
// 跳轉(zhuǎn)
window.location.;
});
}
結(jié)果:
添加完成后,頁面會跳轉(zhuǎn)到購物車結(jié)算頁面:cart.html
3.3.查詢購物車
3.3.1.校驗用戶登錄
因為會多次校驗用戶登錄狀態(tài)绷蹲,因此我們封裝一個校驗的方法:
在common.js中:
3.3.2.查詢購物車
頁面加載時,就應(yīng)該去查詢購物車顾孽。
var cartVm = new Vue({
el: "#cartApp",
data: {
ly,
carts: [],// 購物車數(shù)據(jù)
},
created() {
this.loadCarts();
},
methods: {
loadCarts() {
// 先判斷登錄狀態(tài)
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的數(shù)據(jù):
頁面位置:
修改后:
要注意若厚,價格的展示需要進行格式化拦英,這里使用的是我們在common.js中定義的formatPrice方法:
效果:
[圖片上傳失敗...(image-4b986b-1556198414795)]
3.6.修改數(shù)量
我們給頁面的 +
和 -
綁定點擊事件,修改num 的值:
兩個事件:
increment(c) {
c.num++;
ly.verifyUser()
.then(() => {
// TODO 已登錄测秸,向后臺發(fā)起請求
})
.catch(() => {
// 未登錄疤估,直接操作本地數(shù)據(jù)
ly.store.set("carts", this.carts);
})
},
decrement(c) {
if (c.num <= 1) {
return;
}
c.num--;
this.verifyUser()
.then(() => {
// TODO 已登錄,向后臺發(fā)起請求
})
.catch(() => {
// 未登錄霎冯,直接操作本地數(shù)據(jù)
ly.store.set("carts", this.carts);
})
},
3.7.刪除商品
給刪除按鈕綁定事件:
點擊事件中刪除商品:
deleteCart(i) {
this.verifyUser()
.then(() => {
// 已登錄
})
.catch(() => {
// 未登錄
this.carts.splice(i, 1);
ly.store.set("carts", this.carts);
})
}
3.8.選中商品
在頁面中铃拇,每個購物車商品左側(cè),都有一個復(fù)選框沈撞,用戶可以選擇部分商品進行下單慷荔,而不一定是全部:
我們定義一個變量,記錄所有被選中的商品:
3.8.1.選中一個
我們給商品前面的復(fù)選框與selected綁定缠俺,并且指定其值為當(dāng)前購物車商品:
3.8.2.初始化全選
我們在加載完成購物車查詢后显晶,初始化全選:
3.8.4.總價格
然后編寫一個計算屬性贷岸,計算出選中商品總價格:
computed: {
totalPrice() {
return this.selected.map(c => c.num * c.price).reduce((p1, p2) => p1 + p2, 0);
}
}
在頁面中展示總價格:
效果: