【Vue】仿小米商城系统(一)

【Vue】仿小米商城系统(一)

文章目录

  • 【Vue】仿小米商城系统(一)
    • 前言
    • 项目地址:
    • 一、项目概述
      • 项目介绍
      • 商城页面与组件
      • 技术栈
      • 商城各页面展示
        • 商品首页
        • 产品站
        • 商品详情
        • 登录页面:账号 admin 密码 admin
        • 订单确认
        • 购物车页面
        • 订单支付页面
        • 支付宝支付
        • 微信支付
        • 订单列表
      • 项目源码:
    • 二、项目开发前准备
      • 跨域解决
        • jsonp
        • nginx
      • 项目目录结构
      • Storage封装
      • 接口错误拦截
      • Mock设置
        • 集成Mock API(本地集成Mock.js)

前言

本项目是基于Vue全家桶的仿小米商城系统,系列笔记(已完结)如下

【Vue】仿小米商城系统(一)

【Vue】仿小米商城系统(二)

【Vue】仿小米商城系统(三)

【Vue】仿小米商城系统(四)


项目地址:

点击这里仿小米商城系统mimall开发笔记及源码

这里是小飞侠Pan,立志成为一名优秀的前端程序媛!!!

本篇博客收录于我的github前端笔记仓库中,持续更新中,欢迎star~

https://github.com/mengqiuleo/myNote



一、项目概述

项目介绍

本项目是基于Vue全家桶的仿小米商城系统,商城的流程如下:

  • 登录 -> 产品首页 -> 产品站 -> 产品详情
  • 购物车 -> 订单确认 -> 订单支付 -> 订单列表

​ 该项目是对小米商城系统的模仿,实现了从浏览商品到结算商品的整个过程。使用Scss、mixin来对公共样式抽离;对不同页面进行组件复用;商品展示图片使用vue-lazyload实现懒加载;通过vuex实现商品的状态管理,最终实现了登录、浏览商品并加入购物车、结算等功能。

项目源码:Github: 仿小米商城mimall系列学习笔记


商城页面与组件

【Vue】仿小米商城系统(一)_第1张图片

技术栈

【Vue】仿小米商城系统(一)_第2张图片


商城各页面展示

商品首页

首页各个组件的静态代码实现,并实现了图片懒加载,实现了swiper轮播图。

【Vue】仿小米商城系统(一)_第3张图片

产品站

产品站页面吸顶组件、参数组件实现。

【Vue】仿小米商城系统(一)_第4张图片

商品详情

商品详情交互接口实现。

【Vue】仿小米商城系统(一)_第5张图片

登录页面:账号 admin 密码 admin

登录页面交互和接口完整代码实现。

【Vue】仿小米商城系统(一)_第6张图片

订单确认

订单确认页面中部分静态模块实现以及接口功能实现。

【Vue】仿小米商城系统(一)_第7张图片

购物车页面

购物车头部组件以及购物车所有功能的动态交互实现。

【Vue】仿小米商城系统(一)_第8张图片

订单支付页面

订单结算交互实现,同时包含微信支付和支付宝支付同后台对接。

【Vue】仿小米商城系统(一)_第9张图片

支付宝支付

【Vue】仿小米商城系统(一)_第10张图片

微信支付

【Vue】仿小米商城系统(一)_第11张图片

订单列表

【Vue】仿小米商城系统(一)_第12张图片

项目源码:

点击这里 Github: mimall


二、项目开发前准备

跨域解决

jsonp

项目里面使用jsonp,先安装

cnpm i jsonp --save-dev

jsonp不是一个请求,而是一个js脚本。利用了js脚本加载没有限制来进行访问.

在浏览器控制台的XHR中没有,而是在JS中出现(是一个JS脚本)。

在项目中导入,import jsonp from 'jsonp'

然后在mounted中设置,

mounted(){
	let url = "https://www.baidu.com";
	jsonp(url,() => {
		
	})
}

nginx

接口代理 - 通过修改Nginx服务器配置来实现

前端修改,后台不动

在根目录创建配置文件:vue.config.js,在里面配置以下内容:

nodejs服务器遵循的是commonjs规范

设置代理后,

module.exports = {
  devServer:{
    host:'localhost',
    port:8080,
    proxy:{
      '/api':{
        target:'http://mall-pre.xxx.cn',
        changeOrigin:true,
        pathRewrite:{
          '/api':''
        }
      }
    }
  }
}
// 注意:在target里面需要写上接口代理的目标地址

比如有很多接口:

  • http://mall-pre.xxx/server/a.cn
  • http://mall-pre.xxx/server/b.cn
  • http://mall-pre.xxx/server/c.cn

原理: 因为我们需要使用的接口地址可能很多,不可能挨个去进行拦截。所以,这里可以设置一个虚拟的地址/api,实际上,是没有这个地址的。当拦截到/api时,就将主机的点设置为原点(changeOrigin:true),然后添加路径的转发规则,将/api 置为空,转发时就没有/api了


项目目录结构

  • api: 对api的一些处理
  • util:对公共的方法的定义、封装
  • store:使用Vuex的目录
  • pages:项目页面文件
  • storage:数据储存相关
  • assets:小图片、样式文件等
  • components:组件
  • router.js:路由

【Vue】仿小米商城系统(一)_第13张图片

需要注意的是:axios是一个库,并不是vue中的第三方插件,所以使用时需要在每个页面进行导入操作,这样就很麻烦。我们可以使vue-axios将axios的作用域对象挂载到vue实例中,这样就可以在需要使用的时候用this来调用。

Vue.use(VueAxios, axios)

Storage封装

  • storage本身虽然有API,但是只是简单的key/value形式,
  • storage只能存储字符串,需要手工转化为json对象,
  • 并且storage只能一次性的清空,不能进行单个的清空,
  • 我们要向storage中存储一些更复杂的数据形式,所有我们需要对storage进行封装。

这里封装的是sessionStorage,实际上就是可以在sessionStorage存储JSON对象,并且可以对这些对象进行一些操作:

setItem();
getItem();
getStorage();//获取所有数据
clear();
/**
 * Storage封装
 */
const STORAGE_KEY = 'mall';
export default{
  //存储值
  setItem(key,value,module_name){
    if(module_name){
      let val = this.getItem(module_name);
      val[key] = value;
      this.setItem(module_name);
    }else{
      let val = this.getStorage();
      val[key] = value;
      window.sessionStorage.setItem(STORAGE_KEY,JSON.stringify(val));
    }
  },
  //获取某一个模块下面的属性 :user下面的username
  getItem(key,module_name){
    if(module_name){
      let val = this.getItem(module_name);
      if(val) return val[key];
    }
    return this.getStorage()[key];

  },
  getStorage(){
    return JSON.parse(window.sessionStorage.getItem(STORAGE_KEY) || '{}');
  },
  clear(key,module_name){
    let val = this.getStorage();
    if(module_name){
      if(!val[module_name]) return;
      delete val[module_name][key];
    }else{
      delete val[key];
    }
    window.sessionStorage.setItem(STORAGE_KEY,JSON.stringify(val));
  }
} 

接口错误拦截

  • 统一报错
  • 未登录统一拦截
  • 请求值,返回值统一处理

使用axios的拦截器进行处理

//# 根据前端的跨域方式做调整
axios.defaults.baseURL = '/api';
axios.defaults.timeout = 8000;//超时时间为8秒

// # 响应拦截器:接口错误拦截
axios.interceptors.response.use(function(response){
  let res = response.data;//拿到真正的数据
  let path = location.hash;
  if(res.status == 0) {
    return res.data;
  }else if(res.data == 10){
    if(path!='#/index'){
      window.location.href = '/#/login';
    }
    return Promise.reject(res);
  }else{
    Message.error(res.msg);
    return Promise.reject(res);
  }
},(error)=>{
  let res = error.response;
  Message.error(res.data.message);
  return Promise.reject(res);
})

Mock设置

在开发阶段,我们可能还不能拿到API文档,所以可以使用Mock模拟数据来进行数据的交互操作。Mock有以下特点:

  • 开发阶段,为了提高效率,需要提前Mock

  • 减少代码冗余,灵活插拔

  • 较少沟通,减少接口联调时间

使用mock的方法有很多:

  • 本地创建json:在本地创建json文件,然后进行调用
  • easy-mock平台:将baseURL设置为easy-mock的接口地址,调用时和正常调用一样
  • 集成Mock API(本地集成Mock.js)

不管哪一种方法,都是要自己写mock数据。

其实Mock.js 很像 json-server。只不过是一个用在单页面,一个用在vue项目中。

在这个项目里并没有进行Mock.js设置,因为这里的后台完全都有接口数据。


集成Mock API(本地集成Mock.js)

cnpm i mockjs --save-dev

在src中建Mock的API:src/mock/api.js

import Mock from 'mockjs'
Mock.mock('/api/user/login', {
 "status": 0,
  "data": {
    "id": 12,
    "username": "admin",
    "email": "[email protected]",
    "phone": null,
    "role": 0,
    "createTime": 1479048325000,
    "updateTime": 1479048325000
  }
})

之后在main.js设置一个mock的开关:

const mock = true
if(mock){
  require('./mock/api')
}

import是预编译加载,刚打开就会被加载。而require是执行到那一行才会被加载,在这里如果设置mock=false,用require的话那么就永远不会被加载。

但是如果设置import,即使是false,也会被加载。

Mock.js比较好的一点就是,它可以设置返回的数据是随机的。

"status": 0,
  "data": {
    "id" | 10001-11000: 12, //这里设置每次返回的数据是在10001~11000之间,每次不一样
    "username": "@cname", //每次生成随机的名字
    "email": "[email protected]",
    "phone": null,
    "role": 0,
    "createTime": 1479048325000,
    "updateTime": 1479048325000
  }

你可能感兴趣的:(vue,vue.js,前端,javascript)