综合应用 -- 购物车
使用 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
综合应用 -- 购物车相关推荐
- pyhton中的魔术方法
魔术方法 ***** 特殊属性 属性 说明 __name__ 类.函数.方法等的名字 __module__ 类定义所在的模块名 __class__ 对象或类所属的类 __bases__ 类的基类的元组 ...
- Vue学习笔记01-基础部分
文章目录 VUE笔记-01基础 1.简介 mvvm ES6补充 js高阶函数 let/var const 增强字面量写法 2.基础 2.1.引入 2.2.第一个Vue程序 el挂载点 data数据对象 ...
- 安全月报| PeckShield:9月共发生安全事件14起,损失近1,800万美元
据 PeckShield 态势感知平台数据显示,过去一个月,整个区块链生态共发生 14 起较为突出的安全事件,危害程度评级为「中级」,受损金额近 1,800万美元,涉及 DApp 6 起.智能合约 2 ...
- 小白要搭建电商系统,看看这个开源项目!
导语:大家好,我是朋哥,十年码农经验,对技术情有独钟. 实战项目是初学者学习和更高提升自己能力的一种方式. 今天,要和大家分享一个快速发展的开源电子商务平台--Saleor,基于Python和Djan ...
- 前端JavaScript DOM BOM 自学复盘 D3
DOM- 节点操作 1.DOM节点的基本概念 1.1.DOM节点的概念 1.2.节点类型 2.查找节点 2.1.父节点查找: 2.1.1.父节点查找语法: 2.1.2.高级父级查找语法: 2.1.3. ...
- Vue2+3入门到实战
作为IT技术相关行业不可或缺的岗位之一,前端开发工程师就业前途广阔,一直是很多同学心中转行的首选行业.但很多人还没开始,便被一系列问题难倒了,比如:前端该如何入门?路线图是怎样的?想要找到一份好工作, ...
- 【VUE】vue前端框架知识整理
VUE.JS学习笔记 第一章 vue简介 基于VUE框架开发的开源前端项目,这个是我学完后开发的开源实例项目,大家有兴趣的可以一起交流,喜欢的话别忘了star一下哦. 1.1 Vue基本使用 Vue的 ...
- VUE购物车小案例—vue指令的综合应用
需求: 运用Vue基础指令知识实现小小购物车: 涉及到的指令有:v-for.v-model .v-on.v-text 1.能够显示商品名,价格,以及当前商品在购物车的数量 2. 点击 加+ 减- 可 ...
- 云南农职《JavaScript交互式网页设计》 综合机试试卷①——实现购物车的结算
一.语言和环境 实现语言:javascript.html.css. 开发环境:HBuilder. 二.题目2(100分) 1.功能需求: 马上过节了,电商网站要进行促销活动,需要实现该商城购物车的商品 ...
最新文章
- 关于pyecharts 地图显示添加数据的问题
- 比较全面的L1和L2正则化的解释
- pythonshellnohup_python nohup 实现远程运行不宕机操作
- 分布式程序的自动化回归测试
- 三种常见中文内码的转换方法
- JDK源码解析之 java.lang.Exception
- Python的迭代器和生成器
- python restful api_Python利用Django如何写restful api接口详解
- win10 Java JDK环境变量配置
- Markdown 编辑器使用
- 北理计算机未来,2021北理计算机专硕889考研经验分享
- 如何为编程爱好者设计一款好玩的智能硬件(十)——无线2.4G通信模块研究·一篇说完...
- 重装SPS 2003的一点经验
- vue3 + ts + EsLint + Prettier 规范代码
- 一IT公司hr对软件外包感受(转)
- 2021年中国VR/AR行业市场投融资现状分析:VR/AR技术领域融资实现双增长[图]
- “整合”还是“混合”——多因子组合的构建
- Spring事务管理中异常回滚知识点总结
- Day2--使用ESP32双核、U8G2 OLED任务、任务以绝对频率运行、任务内存优化
- Mysql之st_distance_sphere计算两坐标点距离