# vue-ShopProject
**Repository Path**: yayuyang/vue-ShopProject
## Basic Information
- **Project Name**: vue-ShopProject
- **Description**: 后台管理项目的优化练习
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-07-09
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 电商后台管理系统(前端项目)
[后端源码]: https://gitee.com/yayuyang/vue_-shop-project_server
接口API
[前端源码]: https://gitee.com/yayuyang/vue-ShopProject
### 运行步骤:
1 下载后端源码并运行起来
```
npm install
node ./app.js
```
2 安装phpStudy并导入**mydb**
3 使用postman测试api接口(可选)
4 下载前端源码
> npm install
>
> 执行vue ui命令**打开ui界面**,然后**任务 --> 运行server --> 编译成功**,**运行app**查看当前项目效果
### 功能
> 用于管理用户账号,商品分类,商品信息,订单,数据统计等业务功能

### 开发模式
> 电商后台管理系统整体采用前后端分离的开发模式,其中前端项目是基于Vue技术栈的SPA项目
>
> SPA(single page application,单页面应用),整个网站只有一个页面,内容变化通过Ajax局部更新实现,同时支持浏览器地址栏的前进和后退操作
>
>
>
> **基本思路:**
>
> 1. 先将需要用到的组件(统一放在components文件夹)写好。
>
> 为了快速开发,可按需导入第三方插件(plugins/elements.js),减少打包后的项目体积
>
> 2. 给写好的组件合成一个路由(规划路线)(router/index.js)。
>
> 3. 将合成好的路由放到根组件中(路由占位符)。
>
> 4. 将路由器挂载在vue的实例上(main.js)。
>
> 5. 定义瞄点 (body)
>
> 6. 尝试跳转 (body)

### 技术选型
#### 前端项目技术栈
- Vue
- Vue-router
- Element-UI
- Axios
- Echarts
#### 后端项目技术栈
- Node.js
- Express
- Jwt
- Mysql
- Sequelize
### 0 项目初始化
#### 前端项目初始化步骤
1. 安装 Vue 脚手架
2. 通过 脚手架创建项目
3. 配置 Vue-router
4. 配置 Element-UI 组件库
5. 配置 Axios 库
6. 初始化 git 远程仓库
7. 将本地项目托管到github或者码云中
##### 相关依赖-按需导入

#### 后端项目的环境安装配置
1. 安装MySQL数据库,简易安装phpStudy并导入**mysql**数据库数据
2. 安装Node.js环境,node -v,npm -v 检查安装是否成功
3. 配置后台项目,从终端打开后台项目vue_api_server,运行其中的app.js文件(开发中使用)
4. 使用Postman测试后台项目接口是否正常(开发中使用)
### 补充:处理ESLint警告
默认情况下,ESLint和vscode格式化工具有冲突,需要添加配置文件解决冲突。
在项目根目录添加 .prettierrc 文件
### 1 登录概述
#### 1.1 登录业务流程
1. 在登录页面输入账号和密码进行登录,将数据发送给服务器
2. 服务器返回登录的结果,登录成功则返回数据中带有token
3. 客户端得到token并进行保存,后续的请求都需要将此token发送给服务器,服务器会验证token以保证用户身份。
#### 1.2 登录状态保存逻辑
1. http是无状态的
2. 如果服务器和客户端同源,建议可以使用**cookie或者session**来保持登录状态
3. 如果客户端和服务器跨域了,建议使用**token**进行维持登录状态。token是SC之间身份校验
#### 1.3 登录页面的布局
1. main.js文件中 挂载路由,将根组件渲染到页面内
2. 梳理出最简单的模板,
3. 添加表单组件、第三方字体、表单验证、axios 、配置弹窗提示
1. 创建组件,布局(头部和表单)
2. 表单数据绑定、表单数据验证、重置、发起请求、弹窗提示、成功后的行为(保存 token、导航至/home)、路由导航守卫控制
#### 补充:路由导航守卫控制访问权限
> 如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面
>
> 为路由模块添加beforeEach导航守卫
### 2 主页概述
#### 2.1 获取数据的权限
> 后台除了登录接口之外,都需要token权限验证,我们可以通过添加axios请求拦截器来添加token,以保证拥有获取数据的权限
>
> 在入口文件中(main.js)通过axios请求拦截器添加token,保证拥有获取数据的权限
>
#### 2.1主页页面的布局
1. 基本布局:整体为一个container,包含了header和子级container(侧边栏、主体)
2. 侧边栏布局,先导入插件 Menu, Submenu, MenuItem,
3. 添加axios请求拦截器来添加token,以保证拥有获取数据的权限
4. 在created阶段请求左侧菜单数据,通过v-for双重循环渲染左侧菜单
5. 设置激活子菜单样式(el-menu的active-text-color属性),还使用第三方字体图标,还有el-menu中添加一个属性unique-opened,每次只能打开一个子菜单
6. 制作侧边菜单栏的伸缩功能
7. **添加子级路由**(***)
在router.js中导入组件并设置**路由规则**以及子级路由的**默认重定向**/welcome,主体结构中添加一个**路由占位符**,侧边栏二级菜单都改造成子级路由链接,根据菜单的path属性进行路由跳转
8. 当点击二级菜单的时候,被点击的二级子菜单要设置为高亮
将path保存到sessionStorage中,将el-menu的default-active属性设置为activeIndex,最后在created中将sessionStorage中的数据赋值给activeIndex
### 3 用户列表
#### 3.1 基本结构
1. 面包屑组件完成顶部导航路径
2. 卡片组件完成主体表格
3. 输入框组件完成搜索框及搜索按钮
4. 栅格布局来划分结构,使用el-button制作添加用户按钮
#### 3.2 请求数据并分页展示数据
**表格组件**完成列表展示数据,在渲染状态、操作列,使用作用域插槽来进行,还有**文字提示组件、switch开关组件、分页组件**
#### 3.3 子功能实现
状态切换、删除、修改、搜索、添加用户
### 4 权限管理
#### 权限管理业务分析
> 通过权限管理模块可以为用户设置角色,角色包括不同的功能权限
>
> - 编辑角色名称、角色描述、
> - 删除该角色
> - 为该角色分配权限,完成树形结构弹窗
> - 点击左边的三角可以查看该角色的具体权限,使用三重嵌套for循环生成权限下拉列表,美化样式,添加权限删除功能
> - 再回头打开Users.vue,完成分配角色的功能

### 5 商品管理goods
#### 5.1 商品列表list概述
> 具有展示商品信息,搜索是商品和添加商品的功能
>
>
#### 5.2 分类参数paras概述
> 商品参数用于描述商品的特征信息,可以通过电商平台详情页面直观的看到
>
> 添加子级路由,创建组件完成基本布局
>
> 警告提示信息使用了el-alert,级联选择框,添加静态/动态参数、编辑、修改、删除、展示参数
#### 5.3 商品分类cate概述
> 商品分类用于在购物时,快速找到需要购买的商品,进行直观显示
>
> 使用第三方插件vue-table-with-tree-grid展示分类数据,
>
> 使用Cascader组件实现级联菜单显示父级分类
### 6 订单管理
#### 6.1 订单列表概述
>
### 7 数据统计
#### 7.1 数据报表概述
>
### 小结:项目所用依赖
1. 运行依赖
- axios => 发送请求
- echarts => 图表
- element-ui => element ui组件
- moment => 时间处理工具库
- nprogress => 进度条库
- v-viewer => 图片预览工具库
- vue-quill-editor => 富文本编辑器
- vue-table-with-tree-grid => 树形菜单/表格
2. 开发依赖
- babel => es6+语法转换
- eslint/babel-eslint => 语法检查
- less/less-loader => less语法
- babel-plugin-transform-remove-console => 移除console插件
### 8项目优化
> A.生成打包报告,根据报告优化项目
> B.第三方库启用CDN
> C.Element-UI组件按需加载
> D.路由懒加载
> E.首页内容定制
#### 8.1 项目优化策略
##### 8.1.1 生成打包报告
- 通过命令行参数形式生成报告=>vue-cli-service build --report
- **推荐:**通过可视化ui面板直接查看报告(通过控制台和分析面板)
- 通过vue.config.js修改webpack的默认配置
> 通过vue-cli 3.0工具生成的项目,默认隐藏了所有webpack的配置项,目的是为了屏蔽项目的配置过程,让开发人员把工作的重心,放在具体功能和业务逻辑的实现上
>
> 如果我们需要修改配置webpack,则通过新建文件vue.config.js来配置。
- 为开发模式与发布模式指定不同的打包入口
> 默认情况下,vue项目的开发与发布模式,共用同一个打包的入口文件(即src/main.js),为了将项目的开发过程与发布过程分离,可以为两种模式,各自指定打包的入口文件,即:
>
> 1. 开发模式入口文件 src/main-dev.js
> 2. 发布模式入口文件 src/main-prod.js
>
> 方案:configureWebpack(通过链式编程形式)和chainWebpack(通过操作对象形式)
>
> 在vue.config.js导出的配置文件中,新增configureWebpack或chainWebpack节点,来自定义webpack的打包配置
```js
// 代码示例
module.exports = {
chainWebpack: config => {
// 发布模式
config.when(process.env.NODE_ENV === 'production', config => {
//entry找到默认的打包入口,调用clear则是删除默认的打包入口
//add添加新的打包入口
config.entry('app').clear().add('./src/main-prod.js')
})
// 开发模式
config.when(process.env.NODE_ENV === 'development', config => {
config.entry('app').clear().add('./src/main-dev.js')
})
}
}
```
##### 8.1.2 第三方库启用CDN
- 通过externals加载外部cdn资源
> 默认情况下,通过import语法导入的第三方依赖包,最终会打包合并到同一个文件中,从而导致打包成功后,单文件体积过大的问题 => **chunk-vendors**体积过大
>
> 为了解决上述问题,可以通过webpack的externals节点,来配置加载外部的cdn资源,凡是声明在externals中的第三方依赖包,都不会被打包
>
> 原理:在打包期间,webpack先检查externals中有没有声明依赖包,如果有将不会打包进chunk-vendors,在用到这些依赖包的时候,会在全局对象Window找到现成的来使用
1. 步骤1 在vue.config.js如下配置
```js
module.exports = {
chainWebpack: config => {
config.when(process.env.NODE_ENV === 'production', config => {
config.entry('app').clear().add('./src/main-prod.js')
// 在vue.config.js如下配置
config.set('externals', {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
nporgress: 'NProgress',
'vue-quill-editor': 'VueQuillEditor'
})
})
config.when(process.env.NODE_ENV === 'development', config => {
config.entry('app').clear().add('./src/main-dev.js')
})
}
}
```
2. 步骤2
> 在public/index.html文件头部,将main-prod中的已经进行配置的import(样式表)富文本和进度条删除,替换为cdn引入
```css
```
3. 步骤3
> 在public/index.html文件头部,将main-prod中的已经进行配置的import(js文件)删除,替换为cdn引入
>
> 为了保证在全局对象中包含这些依赖包,在index.js头部文件中加入这些的引用
```css
```
4. cdn加速前后对比( **chunk-vendors**打包文件)
> Parsed大小 2.6m=> **596.9kB**
- 使用cdn优化elementui打包

> 具体操作流程
>
> 1. 在main-prod.js中,注释掉element-ui按需加载的代码import './plugins/elements.js'
> 2. 在index.html头部区域中,通过cdn加载element-ui的js和css样式
>
> ``
>
> ``
##### 8.1.3 首页内容定制
> 不同打包环境下,首页内容可能会有所不同,通过插件方式定制
- vue.config.js配置
```js
// 配置。HTML插件。tap函数(修改插件中的相关参数--增加变量args为该插件中的参数项)
config.plugin('html').tap(args => {
args[0].isProd = true或false
// true 表示为产品模式
return args
})
```
- index.html修改
```html
具体内容参考文章底部链接
### 9 项目上线
#### 9.1 通过node创建web服务器
> 新创建文件夹vueshop-server,并安装express,通过express快速创建web服务器,将vue打包生成的dist文件夹,托管为静态资源即可,关键代码如下
```js
// 新创建文件夹vueshop-server,
// 1. npm init -y
// 2. npm i express -S
// 3. 将打包后的dist放入文件夹中
const express = require('express')
// 创建web服务器
const app = express()
// 托管静态资源,注册一个中间件,将制定目录托管为静态资源
app.use(express.static('./dist'))
// 启动web服务器
app.listen(80, () => {
console.log('server runing at http://127.0.0.1')
})
// 5. node app.js启动项目
// 6. http://127.0.0.1浏览器打开该网址
```
#### 9.2 开启gzip配置
> 通过gzip减小文件体积,使传输速度更快

使用gzip后(上面为传输体积,下面为实际体积)

##### 9.2.1 在服务器端使用express做gzip压缩,配置如下
```js
// 1.npm install compression -S
// 2.导入包
const compression = require('compression')
// 3.启用中间件,写在静态资源托管代码之前,先压缩再托管
app.use(compression())
```
#### 9.3 配置https服务
##### 9.3.1 为什么要启用https服务
- 传统的http协议传输的数据都是明文,不安全
- 采用https协议对传输的数据进行了加密处理,可以防止数据被中间人窃取,使用更安全
申请ssl证书(https://freessl.org) => 正常企业还是使用收费ssh(http协议默认运行在80端口,https默认运行在443端口)

#### 9.4 使用pm2管理应用
```js
1. npm i pm2 -g //全局安装
2. pm2 start 脚本(如./app.js) --name 自定义名称 // 启动项目
3. pm2 ls //查看服务器运行的项目
4. pm2 restart 自定义名称 //重启项目
5. pm2 stop 自定义名称 //停止项目
6. pm2 delete 自定义名称 //删除项目
```

### 10 部份页面预览







