- 能够基于Vue初始化项目;
- 能够基于Vue技术进行项目开发;
- 能够使用Vue的第三方组件进行项目开发;
- 能够说出前后端分离的开发模式;
-
客户使用的业务服务:PC端,小程序,移动web,移动app
-
管理员使用的业务服务:PC后台管理端。
-
PC后台管理端的功能:管理用户账号(登录,退出,用户管理,权限管理),商品管理(商品分类,分类参数,商品信息,订单),数据统计
-
电商后台管理系统采用前后端分离的开发模式
-
前端项目是基于Vue的SPA(单页应用程序)项目
-
前端技术栈:Vue,Vue-Router,Element-UI,Axios,Echarts
-
后端技术栈:Node.js,Express,Jwt(模拟session),Mysql,Sequelize(操作数据库的框架)
- 安装Vue脚手架
- 通过脚手架创建项目
- 配置路由
- 配置Element-UI:在插件中安装,搜索
vue-cli-plugin-element
- 配置Axios:在依赖中安装,搜索axios(运行依赖)
- 初始化git仓库
- 将本地项目托管到github或者码云中
参考 "电商管理后台API接口文档.md"
- 在登陆页面输入用户名和密码;
- 调用后台接口进行验证;
- 通过验证之后, 根据后台的响应状态跳转到项目页面;
- http无状态:
- 通过cookie/session记录状态;
- 通过token方式维持状态保持;
注意:
- 前后端不存在跨域, 使用cookie/session;
- 前后端存在跨域, 使用token;
通过权限管理模块控制不同的用户可以进行哪些操作, 具体可以通过角色的方式进行控制, 即每个用户分配一个特定的角色,角色包括不同的权限
商品管理的树形表格是element-ui没有的,所以需要使用vue-table-with-tree-grid
在vue-cli的依赖
中进行安装
商品参数用于显示商品固定的特征信息, 可以通过电商平台详情页直观的看到;
- 动态参数:
- 静态属性:
npm install v-viewer
vue的图片浏览插件
富文本编辑器: 安装依赖(运行依赖) => vue-quill-editor
使用echarts
实现数据报表功能
- 生成打包报告;
- 第三方库的CDN加载;
- Element-UI组件按序加载;
- 路由懒加载;
- 首页内容定制;
使用第三方插件nprogress
github: https://github.com/rstacruz/nprogress
vue-cli中依赖 -> 运行依赖
搜索nprogress
安装即可;
简单的调用start
和done()
来控制进度条
import NProgress from 'nprogress'
NProgress.start();
NProgress.done();
在本项目中, 用过在ajax拦截器中使用调用start
和done()
:
./main.js
...
// 导入nprogress
import NPrpgress from 'nprogress'
import 'nprogress/nprogress.css'
axios.defaults.base = 'http://127.0.0.1:8888/api'
// 在request拦截器中展示进度条
axios.interceptors.request.use(config => {
...
NPrpgress.start()
return config
})
// 在response中隐藏进度条
axios.interceptors.response.use(config => {
NPrpgress.done()
return config
})
Vue.prototype.$http = axios
Vue.config.productionTip = false
...
https://www.npmjs.com/package/babel-plugin-transform-remove-console
在vue-cli
中, 依赖 -> 开发依赖
, 搜索babel-plugin-transform-remove-console
并安装;
./babel.config.js
// 项目发布阶段需要用到的babel插件
const prodPlugins = []
if (process.env.NODE_ENV === 'production') {
// 发布模式
prodPlugins.push('transform-remove-console')
}
module.exports = {
presets: [
,,,
],
plugins: [
[
,,,
],
// 增加节点, 展开节点
...prodPlugins
]
}
打包时, 为了直观地发现项目中存在的问题, 可以在打包时生成报告, 生成报告的方式有两种:
- 通过命令行参数的形式生成报告:
//report 选项可以生成report.html以帮助分析内容
vue-cli-service build --report
通过vue-cli 3.0工具生成的项目, 默认隐藏了所有的webpack的配置项, 目的是为了屏蔽项目的配置过程, 让程序员把工作重心, 放到具体功能和业务上来.
如果程序员有修改webpack默认配置的需求, 可以在项目根目录中, 按需创建webpack.config.js
这个配置文件, 从而对项目的打包发布过程做自定义的配置(具体配置参考:https://cli.vuejs.org/zh/config/#vue-config-js)
// ./webpack.config.js
// 这个文件中, 应该导出一个含有自定义配置项的对象
module.export = {
// 选项
}
默认情况下, vue项目的开发模式
与发布模式
公用同一个打包入口(即./src/main.js). 为了将项目的开发过程与发布过程分离, 可以分为两种模式, 各自指定打包的入口文件, 即:
- 开发模式入口:
./src/main-dev.js
; - 发布模式入口:
./src/main-prod.js
;
在vue.config.js导出的配置对象, 新增configureWebpack 或 chainWebpack节点, 来自定义webpack的打包配置; configureWebpack 和 chainWebpack的作用相同, 唯一的区别在于修改webpack配置的方式不同:
- configureWebpack: 通过
操作对象
的方式来修改默认的webpack配置; - chainWebpack: 通过
连式编程
的方式来修改默认的webpack配置;
代码实例:
// ./vue.config.js
module.exports = {
chainWebpack: config => {
config.when(process.env.NODE_ENV === 'production', config => {
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')
})
}
}
默认情况下, 通过import语法导入的第三方依赖资源,最终会被打包到同一个文件中, 从而导致打包成功后的单文件体积的问题; 可以通过webpack的externals节点, 来配置并加载外部的CDN资源. 凡是声明在externals中的第三方依赖包, 都不会被打包;
代码示例:
// ./vue.config.js
module.exports = {
chainWebpack: config => {
// 发布模式
config.when(process.env.NODE_ENV === 'production', config => {
...
config.set('externals', {
vue: 'vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
nprogress: 'NProgress',
'vue-quill-editor': 'VueQuillEditor'
})
})
config.when(process.env.NODE_ENV === 'development', config => {
// 开发模式
...
})
}
}
<!DOCTYPE html>
<html lang="en">
<head>
...
<link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
<!-- 富文本编辑器 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css" />
<script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.staticfile.org/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js"></script>
<script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>
<!-- 富文本编辑器的 js 文件 -->
<script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-quill-editor.js"></script>
</head>
<body>
...
</body>
</html>
- 在
main-prod.js
中注释掉element-ui按需加载的代码; - 在
index.html
的头部区域, 通过CDN加载element-ui的js和css样式
<!-- ./build/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
...
<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>
<!-- element-ui 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.8.2/theme-chalk/index.css" />
</head>
<body>
...
</body>
</html>
不同的打包环境下, 首页内容可能会有所不同, 可以通过插件的方式进行定制, 插件配置如下:
// ./vue.config.js
module.exports = {
chainWebpack: config => {
// 发布模式
config.when(process.env.NODE_ENV === 'production', config => {
config.plugin('html').tap(args => {
args[0].isProd = true
return args
})
...
})
config.when(process.env.NODE_ENV === 'development', config => {
// 开发模式
config.plugin('html').tap(args => {
args[0].isProd = false
return args
})
...
})
}
}
在index.html中通过参数:
<!-- ./pubilc/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
...
<title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统</title>
<% if(htmlWebpackPlugin.options.isProd){ %>
<link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
...
<% } %>
</head>
<body>
...
</body>
</html>
- 安装
@babel/plugin-syntax-dynamic-import
包; - 在
babel.config.js
配置文件中声明该插件;
,,,
module.exports = {
,,,
plugins: [
,,,
// 增加节点, 展开节点
...prodPlugins,
// 路由懒加载插件
'@babel/plugin-syntax-dynamic-import'
]
}
- 将路由改为按需加载的形式, 示例如下:
// ./src/router/index.js
...
const Login = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Login.vue')
const Home = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Home.vue')
const Welcome = () => import(/* webpackChunkName: "login_home_welcome" */ '../components/Welcome.vue')
const User = () => import(/* webpackChunkName: "user_roghts_roles_cat" */ '../components/user/Users.vue')
const Rights = () => import(/* webpackChunkName: "user_roghts_roles_cat" */ '../components/power/Rights.vue')
const Roles = () => import(/* webpackChunkName: "user_roghts_roles_cat" */ '../components/power/Roles.vue')
const Cat = () => import(/* webpackChunkName: "user_roghts_roles_cat" */ '../components/goods/Cat.vue')
const Params = () => import(/* webpackChunkName: "params_goodslist_addgoods" */ '../components/goods/Params.vue')
const GoodsList = () => import(/* webpackChunkName: "params_goodslist_addgoods" */ '../components/goods/GoodsList.vue')
const addGoods = () => import(/* webpackChunkName: "params_goodslist_addgoods" */ '../components/goods/addGoods.vue')
const Order = () => import(/* webpackChunkName: "order_report" */ '../components/order/Orders.vue')
const Report = () => import(/* webpackChunkName: "order_report" */ '../components/report/report.vue')
Vue.use(VueRouter)
...
创建node项目, 并安装express, 通过express快速创建web服务器, 将vue打包生成的dist文件夹, 托管为静态资源:
- 新建一个目录(./node-server), 并初始化node项目(
npm init -y
) - 安装express, 命令行执行
npm install express
; - 创建启动文件./app.js
const express = require('express')
const app = express()
// 指定静态资源目录
app.use(express.static('../dist'))
app.listen(80, () => {
console.log('server running at http://127.0.0.1')
})
可以通过服务器端使用Express做gzip压缩, 配置如下:
// 安装相应的包
npm install compression -D
// 导入包
const compression = require('compression')
// 开启中间件, 在托管静态资源之前
app.use(compression())
- 安装pm2:
npm install pm2 -g
- 启动项目:
pm2 start 脚本 --name 自定义名称
- 查看运行项目:
pm2 ls
- 重启项目:
pm2 restart 自定义名称
- 停止项目:
pm2 stop 自定义名称
- 删除项目:
pm2 delete 自定义名称