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


    从零开始,搭建一个简单的购物平台(十二)前端商城部分
    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文件

      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/>'
    })
    

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

  • 相关阅读:
    解决: 误将分区的GHO镜像文件恢复到整个硬盘
    腾讯的迷你门户首页新闻用到的Silverlight技术引用
    [转]如何在word文档里面的小方框内打钩
    Microsoft .NET Framework 3.5/4 Client Profile
    Java Web 开发软件下载地址
    tomcat 6.0环境, 网页超链接,文件下载另存为时,不能识别msi文件类型,另存为只能选htm和所有文件。
    英语小记
    去掉WORD文档中向下的小箭头(换行符)
    开个小餐馆要多少成本
    如何租间餐饮店
  • 原文地址:https://www.cnblogs.com/HelloWorld-Yu/p/13806822.html
Copyright © 2020-2023  润新知