从零开始,搭建一个简单的购物平台(十三)前端商城部分

从零开始,搭建一个简单的购物平台(十二)前端商城部分
https://blog.csdn.net/time_____/article/details/108471436
项目源码(持续更新):https://gitee.com/DieHunter/myCode/tree/master/shopping

这篇文章我们来实现一下前端商城的工具类,其他配置和全局状态

工具类:

  • 工具类我们统一放在utils文件夹下,并部署在Vue原型上(与Axios的一样)
  • 首先我们要实现两个对象深复制的方法,之前博客也有介绍到,后续对全局静态变量做操作时,只能将其定义为只读,也就是不能改变他的值,所以深复制是很有必要的,对于简单的数据用json方式即可,遇上含有function,set,get等属性时需要用到递归版。
    JSON:
    export default class Clone {
      static shallowClone(org) {
        return JSON.parse(JSON.stringify(org));
      }
    }
    

    递归:

    export default class Clone {
      static deepClone(org, tag) {
        var tag = tag || {};
        var name = Object.getOwnPropertyNames(org);
        for (var i = 0; i < name.length; i++) {
          var desc = Object.getOwnPropertyDescriptor(org, name[i]);
          if (typeof desc.value === "object" && desc.value !== null) {
            var obj = desc.value.toString() === "[object Object]" ? {} : [];
            Object.defineProperty(tag, name[i], {
              configurable: desc.configurable,
              enumerable: desc.enumerable,
              writable: desc.writable,
              value: obj
            });
            Clone.deepClone(desc.value, obj);
          } else {
            Object.defineProperty(tag, name[i], desc);
          }
        }
        return tag;
      }
    }
    
  • 本地缓存的封装

    import Vue from "vue";
    class Storage {
      static saveStorage(key, val) {
        localStorage.setItem(key, JSON.stringify(val));
      }
      static getStorage(key) {
        try {
          return JSON.parse(localStorage.getItem(key)) || [];
        } catch (error) {}
      }
      static clearStorage(key) {
        try {
          localStorage.removeItem(key);
        } catch (error) {}
      }
    }
    Vue.prototype.$storage = Storage;

其他配置:

  • Events:对全局事件做一个封装,这里针对每一个组件和每一个自定义事件用了一个简单的工厂模式,降低代码的耦合性,解决事件封闭,但是缺点是在每一个组件销毁时需要作事件取消监听(销毁),否则会导致之前的监听事件执行两次,虽然每个子工厂生产出来的都是独特的产品,但是会导致性能降低,所以要做事件销毁处理
    import Vue from "vue";
    class Events extends Vue {//继承Vue的自定义事件,使其直接调用
      constructor() {
        super();
      }
      static getInstance() {//返回当前实例的单例
        if (!Events._instance) {
          Object.defineProperty(Events, "_instance", {
            value: new Events()
          });
        }
        return Events._instance;
      }
      onEvent(_event, _fn) {
        this.$on(_event, _fn);
      }
      onceEvent(_event, _fn) {
        this.$once(_event, _fn);
      }
      emitEvent(_event, _data) {
        this.$emit(_event, _data);
      }
      offEvent(_event, _fn) {
        this.$off(_event, _fn)
      }
    }
    Vue.prototype.$events = Events.getInstance()
    
  • 全国省市县的JSON文件
    https://gitee.com/DieHunter/myCode/blob/master/shopping/client/shopclient/src/config/city.js 

  • 静态Config文件

    扫描二维码关注公众号,回复: 11993541 查看本文章
    export default class Config {
      static Agreement = "http://"; //协议
      static BaseUrl = "127.0.0.1"; //请求ip或域名
      static ServerUrl = ""; //多级路径名
      static ServerPort = ":1024"; //端口
      static Path = "/"; //静态文件目录
      static CryptoKey = "tokenkey"; //加密信息关键字
      static RequestPath =
        Config.Agreement + Config.BaseUrl + Config.ServerPort + Config.Path; //服务端静态目录
      static RequestTimeOut = 10 * 1000; //请求超时时间
      static GetCodeTime = 60 * 1000; //邮箱验证码重发时间
      static ShopMaxCount = [1, 2, 3, 4, 5, 6, 7, 8, 9]; //每件商品可购买数量(选择器配置)
      static ServerApi = {
        //接口名
        token: "user/checkToken", //验证token
        user: {
          userLogin: "user/userLogin", //用户登录
          getMailCode: "user/getMailCode", //获取验证码
          updateUser: "user/updateUser", //更新用户
          userReg: "user/userReg" //注册(移动端)
        },
        shop: {
          shopList: "shop/shopList" //获取商品列表
        },
        order: {
          orderList: "order/orderList", //获取订单列表
          addOrder: "order/addOrder", //新增订单
          delOrder: "order/delOrder", //删除订单
          updateOrder: "order/updateOrder" //更新订单状态
        }
      };
      static UploadName = {
        headPic: "upload/headPic" //图片路径
      };
      static UploadKey = {
        headKey: "headPic" //头像上传关键字
      };
      static StorageName = {
        //本地缓存
        Token: "token",
        ShopCar: "shopCar", //购物车列表
        UserInfo: "userInfo" //用户信息
      };
      static EventName = {
        //自定义事件
        SelectKind: "selectKind", //分类选择
        ChangeCount: "changeCount", //修改商品数量
        ShowPicker: "showPicker", //显示,隐藏Picker
        CountShop: "countShop", //购物车商品总价
        SelectAllChild: "selectAllChild", //全选子选项
        SelectParent: "selectParent", //全选父选项
        IsLogin: "isLogin", //登录成功
        UploadPic: "uploadPic" //上传图片
      };
      static DefaultPageConfig = {
        //默认分页配置
        shopType: "",
        picType: "",
        keyWord: "",
        page: 1,
        isactive: true,
        pageSize: "",
        totalPage: 1,
        orderId: "",
        sort: "1",
        orderState: ""
      };
    }
    
  • 邮箱类型选择配置 

    export default class Mail {
      static address = [
        "@qq.com",
        "@gmail.com",
        "@yahoo.com",
        "@msn.com",
        "@hotmail.com",
        "@aol.com",
        "@ask.com",
        "@live.com",
        "@0355.net",
        "@163.com",
        "@163.net",
        "@263.net",
        "@3721.net",
        "@yeah.net",
        "@googlemail.com",
        "@mail.com"
      ];
    }
    
  • 商品类型

    export default class ShopType {
      //商品类型,图片类型,订单状态
      static shopType = [
        { name: "炒货", val: "0" },
        { name: "果味", val: "1" },
        { name: "蔬菜", val: "2" },
        { name: "点心", val: "3" },
        { name: "粗茶", val: "4" },
        { name: "淡饭", val: "5" }
        // { name: "其他", val: "6" },
      ];
      static picType = [
        { name: "单个商品", val: "0" },
        { name: "轮播图", val: "1" },
        { name: "分类", val: "2" },
        { name: "主题", val: "3" },
        { name: "其他", val: "4" }
      ];
      static orderState = [
        { name: "未付款", val: "0" },
        { name: "已付款", val: "1" },
        { name: "未发货", val: "2" },
        { name: "已发货", val: "3" },
        { name: "已完成", val: "4" },
        { name: "已退款", val: "5" }
      ];
    }
    

全局Store

  • 全局store没有用Vuex,而是用本地缓存做了一个数据存储,在src下新建store文件夹,并新建store.js文件将所有的状态值汇总并暴露,这里我们简单搭建一下购物车,在shopCar中新建数据model层state和命令控制controller层action
  • store.js
    import Vue from 'vue'
    import ShopCar from "./shopCar/action"
    Vue.prototype.$store = {
      ShopCar
    }
    
     
  • state.js
    import Vue from "vue"
    import Config from "../../config/config"
    export default class State extends Vue {
      constructor() {
        super()
      }
      set shopCar(val) {//写数据
        this.$storage.saveStorage(Config.StorageName.ShopCar, val)
      }
      get shopCar() {//读数据
        return this.$storage.getStorage(Config.StorageName.ShopCar) || []
      }
    }
    
  •  action.js

    import State from "./state"
    import Vue from "vue"
    import Config from "../../config/config"
    const {
      EventName
    } = Config;
    export default class Action extends Vue {
      constructor() {
        super()
        this._state = new State()
      }
      set state(val) {
        this._state.shopCar = val
      }
      get state() {
        return this._state.shopCar
      }
      countShopItem() {//修改商品数量
        
      }
      delShopItem() {//删除商品
        
      }
      selAllChild() {//全选
        
      }
      filterSelect() {//刷新商品列表
        
      }
      delSelShop() {//删除选择商品
        
      }
    }
    

引入所有包

import Vue from 'vue'
import App from './App'
import router from './router'
import "./style/main.less"
import 'mint-ui/lib/style.css'
import MintUI from 'mint-ui'
import './utils/axios'
import './utils/cryptoTool'
import './utils/storage'
import "./event/event"
import "./store/store"
Vue.use(MintUI);
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: {
    App
  },
  template: '<App/>'
})

到此为止,前端商城准备工作全部完成,下一篇文章正式开始进入开发

猜你喜欢

转载自blog.csdn.net/time_____/article/details/108514710