综合应用 -- 购物车

Posted 沿着路走到底

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了综合应用 -- 购物车相关的知识,希望对你有一定的参考价值。

使用 jQuery 做一个模拟购物车的示例

包括:显示购物列表、加入购物车、从购物车删除

项目演示

点击 加入购物车 按钮,将商品加入购物车,并打印日志上报

点击 购物车 按钮,展示购物车内容

点击 从购物车删除 按钮,将商品从购物车删除,并打印日志上报

用到的设计模式

工厂模式、单例模式

装饰器模式、观察者模式

状态模式、模板方法模式、代理模式

UML类图

项目目录

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>设计模式 - 购物车</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>

list.json

[
    
        "id": 1,
        "name": "《JS 基础面试题》",
        "price": 149,
        "discount": 1
    ,
    
        "id": 2,
        "name": "《JS 高级面试题》",
        "price": 366,
        "discount": 1
    ,
    
        "id": 3,
        "name": "《React 模拟大众点评 webapp》",
        "price": 248,
        "discount": 0
    ,
    
        "id": 4,
        "name": "《zepto 设计与源码解读》",
        "price": 0,
        "discount": 0
    
]

index.js

import App from './demo/App.js'

let app = new App('app')
app.init()

App.js

import $ from 'jquery'
import ShoppingCart from './ShoppingCart/ShoppingCart.js'
import List from './List/List.js'

export default class App 
    constructor(id) 
        this.$el = $(`#$id`)
    

    // 初始化购物车
    initShoppingCart() 
        let shoppingCart = new ShoppingCart(this)
        shoppingCart.init()
    

    // 初始化商品列表
    initList() 
        let list = new List(this)
        list.init()
    

    init() 
        this.initShoppingCart()
        this.initList()
    

config.js

export const GET_LIST = '/api/list.json'

List.js

import $ from 'jquery'
import createItem from '../Item/CreateItem.js'
import  GET_LIST  from '../config/config.js'

export default class List 
    constructor(app) 
        this.app = app
        this.$el = $('<div>')
    

    // 获取数据
    loadData() 
        // 使用 fetch (低版本浏览器可使用 https://github.com/github/fetch 兼容)
        // 返回 promise
        return fetch(GET_LIST).then(result => 
            return result.json()
        )
    

    // 生成列表
    initItemList(data) 
        data.map(itemData => 
            let item = createItem(this, itemData)
            item.init()
            return item
        )
    

    // 渲染
    render() 
        this.app.$el.append(this.$el)
    

    init() 
        this.loadData().then(data => 
            this.initItemList(data)
        ).then(() => 
            // 最后再一起渲染 DOM ,以避免重复渲染的性能问题
            this.render()
        )
    

CreateItem.js

import Item from './Item.js'

function createDiscount(item) 
    // 用代理模式做折扣显示
    return new Proxy(item, 
        get: function (target, key, receiver) 
            if (key === 'name') 
                return `$target[key]【折扣】`
            
            if (key === 'price') 
                return target[key] * 0.8
            
            return target[key]
        
    )


// 工厂函数
export default function (list, itemData) 
    if (itemData.discount) 
        itemData = createDiscount(itemData)
    
    return new Item(list, itemData)

Item.js

import $ from 'jquery'
import StateMachine from 'javascript-state-machine'
import  log  from '../util/log.js'
import getCart from '../ShoppingCart/GetCart.js'

export default class Item 
    constructor(list, data) 
        this.list = list
        this.data = data
        this.$el = $('<div>')
        this.cart = getCart()
    

    initContent() 
        let $el = this.$el
        let data = this.data
        $el.append($(`<p>名称:$data.name</p>`))
        $el.append($(`<p>价格:$data.price</p>`))
    

    initBtn() 
        let $el = this.$el
        let $btn = $('<button>')

        // 状态管理 状态模式管理按纽添加删除操作
        let _this = this
        let fsm = new StateMachine(
            init: '加入购物车',
            transitions: [
                
                    name: 'addToCart', 
                    from: '加入购物车',
                    to: '从购物车删除'
                ,
                
                    name: 'deleteFromCart',
                    from: '从购物车删除',
                    to: '加入购物车'
                
            ],
            methods: 
                // 加入购物车
                onAddToCart: function () 
                    _this.addToCartHandle()
                    updateText()
                ,
                // 删除
                onDeleteFromCart: function () 
                    _this.deleteFromCartHandle()
                    updateText()
                
            
        )
        function updateText() 
            $btn.text(fsm.state)
        

        $btn.click(() => 
            if (fsm.is('加入购物车')) 
                fsm.addToCart()
             else 
                fsm.deleteFromCart()
            
        )
        updateText()

        $el.append($btn)
    

    // 加入购物车
    @log('add')
    addToCartHandle() 
        this.cart.add(this.data)
    

    // 从购物车删除
    @log('del')
    deleteFromCartHandle() 
        this.cart.del(this.data.id)
    

    render() 
        this.list.$el.append(this.$el)
    

    init() 
        this.initContent()
        this.initBtn()
        this.render()
    

log.js

export function log(type) 
    return function (target, name, descriptor) 
        var oldValue = descriptor.value;
    
        descriptor.value = function() 
            //  此处统一上报日志
            console.log(`日志上报 $type`);
    
            // 执行原有方法
            return oldValue.apply(this, arguments);
        ;
    
        return descriptor;
    

GetCart.js

class Cart 
    constructor() 
        this.list = []
    
    add(data) 
        this.list.push(data)
    
    del(id) 
        this.list = this.list.filter(item => 
            if (item.id === id) 
                return false
            
            return true
        )
    
    getList() 
        return this.list.map(item => 
            return item.name
        ).join('\\n')
    


// 返回单例
let getCart = (function () 
    let cart
    return function () 
        if (!cart) 
            cart = new Cart();
        
        return cart
    
)()

export default getCart

ShoppingCart.js

import $ from 'jquery'
import getCart from './GetCart.js'

export default class ShoppingCart 
    constructor(app) 
        this.app = app
        this.$el = $('<div>').css(
            'padding-bottom': '10px',
            'border-bottom': '1px solid #ccc'
        )
        this.cart = getCart()
    

    // 显示购物车内容
    showCart() 
        alert(this.cart.getList())
    

    // 初始化按钮
    initBtn() 
        let $btn = $('<button>购物车</button>')
        $btn.click(() => 
            this.showCart()
        )
        this.$el.append($btn)
    

    // 渲染
    render() 
        this.app.$el.append(this.$el)
    

    init() 
        this.initBtn()
        this.render()
    

1

以上是关于综合应用 -- 购物车的主要内容,如果未能解决你的问题,请参考以下文章

ios15--综合小例子

删除 Woocommerce 中特定产品类别的添加购物车按钮

text Woocommerce - 删除价格并添加到购物车按钮(目录模式)

营销购物篮理念的技术

当我按下购物车按钮时,我的应用程序崩溃了

Paypal 与 iphone 中的购物车按钮