使用 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 = appthis.$el = $('<div>')}// 获取数据loadData() {// 使用 fetch (低版本浏览器可使用 https://github.com/github/fetch 兼容)// 返回 promisereturn 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 = listthis.data = datathis.$el = $('<div>')this.cart = getCart()}initContent() {let $el = this.$ellet data = this.data$el.append($(`<p>名称:${data.name}</p>`))$el.append($(`<p>价格:${data.price}</p>`))}initBtn() {let $el = this.$ellet $btn = $('<button>')// 状态管理 状态模式管理按纽添加删除操作let _this = thislet 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 cartreturn 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 = appthis.$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()}
}

总结用到的设计模式

工厂模式

$('xxx'),

创建商品

单例模式

购物车

装饰器模式

打点统计

观察者模式

网页事件

Promise

状态模式

添加到购物车 &  从购物车删除

代理模式

打折商品信息处理

模板方法模式

init函数

1

综合应用 -- 购物车相关推荐

  1. pyhton中的魔术方法

    魔术方法 ***** 特殊属性 属性 说明 __name__ 类.函数.方法等的名字 __module__ 类定义所在的模块名 __class__ 对象或类所属的类 __bases__ 类的基类的元组 ...

  2. Vue学习笔记01-基础部分

    文章目录 VUE笔记-01基础 1.简介 mvvm ES6补充 js高阶函数 let/var const 增强字面量写法 2.基础 2.1.引入 2.2.第一个Vue程序 el挂载点 data数据对象 ...

  3. 安全月报| PeckShield:9月共发生安全事件14起,损失近1,800万美元

    据 PeckShield 态势感知平台数据显示,过去一个月,整个区块链生态共发生 14 起较为突出的安全事件,危害程度评级为「中级」,受损金额近 1,800万美元,涉及 DApp 6 起.智能合约 2 ...

  4. 小白要搭建电商系统,看看这个开源项目!

    导语:大家好,我是朋哥,十年码农经验,对技术情有独钟. 实战项目是初学者学习和更高提升自己能力的一种方式. 今天,要和大家分享一个快速发展的开源电子商务平台--Saleor,基于Python和Djan ...

  5. 前端JavaScript DOM BOM 自学复盘 D3

    DOM- 节点操作 1.DOM节点的基本概念 1.1.DOM节点的概念 1.2.节点类型 2.查找节点 2.1.父节点查找: 2.1.1.父节点查找语法: 2.1.2.高级父级查找语法: 2.1.3. ...

  6. Vue2+3入门到实战

    作为IT技术相关行业不可或缺的岗位之一,前端开发工程师就业前途广阔,一直是很多同学心中转行的首选行业.但很多人还没开始,便被一系列问题难倒了,比如:前端该如何入门?路线图是怎样的?想要找到一份好工作, ...

  7. 【VUE】vue前端框架知识整理

    VUE.JS学习笔记 第一章 vue简介 基于VUE框架开发的开源前端项目,这个是我学完后开发的开源实例项目,大家有兴趣的可以一起交流,喜欢的话别忘了star一下哦. 1.1 Vue基本使用 Vue的 ...

  8. VUE购物车小案例—vue指令的综合应用

    需求: 运用Vue基础指令知识实现小小购物车: 涉及到的指令有:v-for.v-model .v-on.v-text 1.能够显示商品名,价格,以及当前商品在购物车的数量 2. 点击 加+ 减-  可 ...

  9. 云南农职《JavaScript交互式网页设计》 综合机试试卷①——实现购物车的结算

    一.语言和环境 实现语言:javascript.html.css. 开发环境:HBuilder. 二.题目2(100分) 1.功能需求: 马上过节了,电商网站要进行促销活动,需要实现该商城购物车的商品 ...

最新文章

  1. 关于pyecharts 地图显示添加数据的问题
  2. 比较全面的L1和L2正则化的解释
  3. pythonshellnohup_python nohup 实现远程运行不宕机操作
  4. 分布式程序的自动化回归测试
  5. 三种常见中文内码的转换方法
  6. JDK源码解析之 java.lang.Exception
  7. Python的迭代器和生成器
  8. python restful api_Python利用Django如何写restful api接口详解
  9. win10 Java JDK环境变量配置
  10. Markdown 编辑器使用
  11. 北理计算机未来,2021北理计算机专硕889考研经验分享
  12. 如何为编程爱好者设计一款好玩的智能硬件(十)——无线2.4G通信模块研究·一篇说完...
  13. 重装SPS 2003的一点经验
  14. vue3 + ts + EsLint + Prettier 规范代码
  15. 一IT公司hr对软件外包感受(转)
  16. 2021年中国VR/AR行业市场投融资现状分析:VR/AR技术领域融资实现双增长[图]
  17. “整合”还是“混合”——多因子组合的构建
  18. Spring事务管理中异常回滚知识点总结
  19. Day2--使用ESP32双核、U8G2 OLED任务、任务以绝对频率运行、任务内存优化
  20. Mysql之st_distance_sphere计算两坐标点距离

热门文章

  1. flex弹性盒子(伸缩盒模型)的使用
  2. OpenCV之灰度空间变换
  3. 获得淘宝商品详情原数据接口调用展示
  4. Cache 的地址映像方式(4种)
  5. chrome浏览器中使用adblockplus拦截广告
  6. sklearn决策树--泰坦尼克号幸存者预测
  7. 实战演练-java+微信小程序实现省市区三级联动
  8. mx450和gtx1050ti哪个好
  9. WGS84经纬度坐标6度分带高斯投影正算
  10. 交换机虚拟化和堆叠的区别_网工知识角|一分钟记熟NFV网络功能虚拟化技术介绍...