乐优商城(三十二)——购物车

目录

一、搭建购物车微服务

1.1 创建module

1.2 pom依赖

1.3 配置文件

1.4 启动类

二、购物车功能分析

2.1 需求

2.2 流程图

三、未登录购物车

3.1 准备

3.1.1 购物车的数据结构

3.1.2 web本地存储

3.1.3 获取num

3.2 添加购物车

3.2.1 点击事件

3.2.2 获取数量、添加购物车

3.3 查询购物车

3.3.1 校验用户登录

3.3.2 查询购物车

3.3.3 渲染到页面

3.4 修改数量

3.5 删除商品

3.6 选中商品

3.6.1 选中一个

3.6.2 全部选中

3.6.3 初始化全选

3.6.4 总价格

3.6.5 总数量


一、搭建购物车微服务

1.1 创建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.cart</groupId>
    <artifactId>leyou-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.19.121
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
    registry-fetch-interval-seconds: 10
  instance:
    instance-id: ${spring.application.name}:${server.port}
    prefer-ip-address: true  #当你获取host时,返回的不是主机名,而是ip
    ip-address: 127.0.0.1
    lease-expiration-duration-in-seconds: 10 #10秒不发送九过期
    lease-renewal-interval-in-seconds: 5 #每隔5秒发一次心跳

1.4 启动类

package com.leyou.cart;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @Author: 98050
 * @Time: 2018-10-24 20:46
 * @Feature:购物车启动器
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class LyCartApplication {

    public static void main(String[] args) {
        SpringApplication.run(LyCartApplication.class,args);
    }
}

二、购物车功能分析

2.1 需求

需求描述:

  • 用户可以在登录状态下将商品添加到购物车

    • 放入数据库

    • 放入redis(采用)

  • 用户可以在未登录状态下将商品添加到购物车

    • 放入localstorage

  • 用户可以使用购物车一起结算下单

  • 用户可以查询自己的购物车

  • 用户可以在购物车中修改购买商品的数量。

  • 用户可以在购物车中删除商品。

  • 在购物车中展示商品优惠信息

  • 提示购物车商品价格变化

2.2 流程图

这幅图主要描述了两个功能:新增商品到购物车、查询购物车。

新增商品:

  • 判断是否登录

    • 是:则添加商品到后台Redis中

    • 否:则添加商品到本地的Localstorage

无论哪种新增,完成后都需要查询购物车列表:

  • 判断是否登录

    • 否:直接查询localstorage中数据并展示

    • 是:已登录,则需要先看本地是否有数据,

      • 有:需要提交到后台添加到redis,合并数据,而后查询

      • 否:直接去后台查询redis,而后返回

三、未登录购物车

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.http.get("/auth/verify").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.image,
                            num:this.num,
                            ownSpec:JSON.stringify(this.ownSpec)
                        };
                        carts.push(cart);
                    }
                    //5.把carts写回到localStorage
                    ly.store.set("carts",carts);
                    //6.跳转
                    window.location.href = "http://www.leyou.com/cart.html";
                });
            }

结果:

添加完成后,页面会跳转到购物车结算页面:cart.html

3.3 查询购物车

3.3.1 校验用户登录

因为校验用户会多次进行,所以在common.js中将其封装为一个方法:

然后调用:

3.3.2 查询购物车

页面加载时,就应该去查询购物车。

var cartVm = new Vue({
        el: "#cartApp",
        data: {
            ly,
            carts:[], //购物车数据
        },
        components: {
            shortcut: () => import("/js/pages/shortcut.js")
        },
        created(){
            this.loadCarts();
        },
        methods:{
            loadCarts(){
                //1.先判断登录状态
                ly.verifyUser().then(() => {
                    //2.已经登录
                }).catch(() => {
                    //3.未登陆
                    this.carts = ly.store.get("carts") || [];
                })
            }
        }
    })

刷新页面,查看数据:

3.3.3 渲染到页面

效果:

3.4 修改数量

给页面的 +-绑定点击事件,修改num 的值:

            increment(c){
                c.num++;
                ly.verifyUser().then(() =>{
                    //已经登录,向后台发起请求
                }).catch(() => {
                    //未登录,直接操作本地数据库
                    ly.store.set("carts",this.carts);
                })
            },
            decrement(c){
                if (c.num <= 1){
                    return;
                } 
                c.num--;
                ly.verifyUser().then(() =>{
                    //已经登录,向后台发起请求
                }).catch(() => {
                    //未登录,直接操作本地数据库
                    ly.store.set("carts",this.carts);
                })
            },

3.5 删除商品

给删除按钮绑定事件:

deleteCart(i){
                ly.verifyUser().then(() =>{
                    //已经登录,向后台发起请求
                }).catch(() => {
                    //未登录,直接操作本地数据库
                    this.carts.splice(i,1);
                    ly.store.set("carts",this.carts);
                })
}

3.6 选中商品

在页面中,每个购物车商品左侧,都有一个复选框,用户可以选择部分商品进行下单,而不一定是全部:

定义一个变量,记录所有被选中的商品:

3.6.1 选中一个

给商品前的复选框与selected绑定,并且指定其值为当前购物车商品:

3.6.2 全部选中

分析

页面方法绑定

上:

中:

下:

代码

loadCarts: function () {
                //1.先判断登录状态
                ly.verifyUser().then(() => {
                    //2.已经登录
                }).catch(() => {
                    //3.未登陆
                    this.carts = ly.store.get("carts") || [];
                    this.selected = this.carts;
                    this.$refs.selectAllTop.checked = true;
                    this.$refs.selectAllBottom.checked = true;
                })
            }

初始化是全选的。

            selectAll(){
                if(this.selected.length !== ly.store.get("carts").length){
                    this.selected = this.carts;
                }else  {
                    this.selected = [];
                }
            },
            selectSingle(){

                console.log(this.selected.length);
                console.log(ly.store.get("carts").length);

                if(this.selected.length !== ly.store.get("carts").length - 1){
                    this.$refs.selectAllTop.checked=false;
                    this.$refs.selectAllBottom.checked=false;
                }else{
                    this.$refs.selectAllTop.checked=true;
                    this.$refs.selectAllBottom.checked=true;
                }
            }

注意:为什么要减1?

因为selected和商品选择按钮是双向绑定,当单击按钮时,获取的selected的长度是改变前的长度,所以要进行修正,可自行实验。

3.6.3 初始化全选

加载完成购物车查询后,初始化全选:

3.6.4 总价格

编写计算属性,计算选中商品的总价格:

        computed:{
          totalPrice(){
              return ly.formatPrice(this.selected.reduce((c1,c2) => c1+c2.num*c2.price,0))
          }
        }

3.6.5 总数量

编写计算属性:

totalNum(){
              return this.selected.reduce((c1,c2) => c1+c2.num,0);
          }

效果:

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值