设计模式之实战(8-1)

143 阅读2分钟

1、写一个购物车 UML 类图

image.png

image.png

image.png

  • 自己画一遍

image.png

2、写代码之 环境准备

1、配置一下 代理

image.png

2、新建 json 文件

  • 然后 http-server -p 8880 启动服务

image.png

3、安装 jQuery yarn add jquery --save

4、需要一个容器 div

image.png

5、初始化 App.js

image.png

6、index.js

image.png

3、实现 List 组件

1、完善 App.js

import $ from "jquery";

export default class App {
  constructor(id) {
    this.$el = $("#" + id);
  }

  // 初始化购物车
  initShoppingCart() {}

  // 初始化列表
  initList() {}
  init() {
    this.initShoppingCart();
    this.initList();
  }
}

2、新建 List 文件夹和 ShoppingCart 文件夹

image.png

image.png

image.png

  • List 执行 差不多相同的操作

image.png

image.png

3、demo下 新建 config.js文件

image.png

4、完善 List.js

import $ from "jquery";
import { GET_LIST } from "../config/config";

export default class List {
  constructor(app) {
    this.app = app;
    this.$el = $("<div>"); // 创建div
  }
  // 获取数据
  loadData() {
    // 返回 Promise 实例
    return fetch(GET_LIST).then((result) => {
      return result.json();
    });
  }

  // 生成列表
  initItemList(data) {
    data.map((initData) => {
      // 创建一个 Item 然后 init
    });
  }

  // 渲染
  render() {
    this.app.$el.append(this.$el); // 将当前的div(this.$el) 插入到app的$el里面去
  }

  init() {
    // 先加载数据
    this.loadData()
      .then((data) => {
        // 然后 渲染列表
        this.initItemList(data);
      })
      .then(() => {
        // 最后执行 渲染
        this.render();
      });
  }
}

5、完善 json文件

6、写Cart

  • 此处 没有直接 写 一个 class Cart 而是 使用 单例模式
  constructor() {
    this.list = []; // 初始化 数组
  }

  add(data) {
    this.list.push(data); //  经典的 数组 push 方法
  }

  del(id) {
    this.list = this.list.filter((item) => {
      // 经典 数组 filter 方法
      if (item.id === id) {
        return false;
      }
      return true;
    });
  }

  getList() {
    return this.list
      .map((item) => {
        //  经典数组 map 方法
        return item.name;
      })
      .join("\n"); // 经典 join 进行连接
  }
}

// js 返回单例  使用 匿名函数
let getCart = (function () {
  let cart;
  return function () {
    if (!cart) {
      cart = new Cart();
    }
    return cart;
  };
})();

export default getCart; //  此处导出的是 函数 而不是 Cart  class 类
  • 非常的精彩

7、List 文件夹下 新建 Item.js

import $ from "jquery";
import getCart from "../ShoppingCart/GetCart";

class Item {
  constructor(list, data) {
    this.$el = $("<div>");
    this.list = list;
    this.data = data;
    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>test</button>");

    $btn.click(() => {
      // 添加购物车
      // 从购物车 删除
    });

    $el.append($btn);
  }

  // 添加到购物车
  addToCartHandle() {
    this.cart.add(this.data);
  }

  // 从购物车删除
  deleteFromCartHandle() {
    this.cart.del(this.data.id);
  }

  render() {
    this.list.$el.append(this.$el);
  }

  init() {
    this.initContent();
    this.initBtn();
    this.render();
  }
}

8、List下 新建 CreateItem.js

  • 函数内 return new XXX() 为典型的工厂模式
import Item from "./Item";

// 后续会补充 优惠商品的处理逻辑

// 工厂函数
export default function (list, itemData) {
  return new Item(list, itemData);
}

9、List.js 中使用 这个工厂函数

image.png

image.png

10、完善 Item.js 使用 状态机控制 按钮状态的变化

import getCart from "../ShoppingCart/GetCart";
import { StateMachine } from "javascript-state-machine";

class Item {
  constructor(list, data) {
    this.$el = $("<div>");
    this.list = list;
    this.data = data;
    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 fsm = new StateMachine({
      init: "加入购物车",
      transitions: [
        {
          name: "addToCart",
          from: "加入购物车",
          to: "从购物车删除",
        },
        {
          name: "deleteFromCart",
          from: "从购物车删除",
          to: "加入购物车",
        },
      ],

      methods: {
        // 加入购物车
        onAddToCart: () => {
          this.addToCartHandle();
          updateText();
        },
        // 从购物车 删除
        onDeleteFromCart: () => {
          this.deleteFromCartHandle();
          updateText();
        },
      },
    });

    function updateText() {
      $btn.text(fsm.state);
    }

    $btn.click(() => {
      // 添加购物车
      // 从购物车 删除
      if(fsm.is('加入购物车')){
          fsm.addToCart()
      }else{
          fsm.deleteFromCart()
      }
    });
    updateText();
    $el.append($btn);
  }

  // 添加到购物车
  addToCartHandle() {
    this.cart.add(this.data);
  }

  // 从购物车删除
  deleteFromCartHandle() {
    this.cart.del(this.data.id);
  }

  render() {
    this.list.$el.append(this.$el);
  }

  init() {
    this.initContent();
    this.initBtn();
    this.render();
  }
}

11、完善 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()
    }
}

12、基本功能完结!