# vue_shop_admin
**Repository Path**: chmingx/vue_shop_admin
## Basic Information
- **Project Name**: vue_shop_admin
- **Description**: vue开发的后台管理项目
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-10-07
- **Last Updated**: 2021-11-25
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# admin
vue后台管理项目
## 项目初始化
```shell
# 创建Vue项目
vue create vue_shop_admin
# 配置vue路由
# 配置Element-UI组件库
# 配置axios库
```
## 登录和退出
```shell
npm install less-loader@4.1.0 --save-dev
npm install less@3.9.0 --save-dev
```
路由导航守卫
如果用户没有登录,但直接通过URL访问特定页面,需要重新导航到登录页面
```js
// 为路由对象添加beforeEach导航守卫
router.beforeEach((to, from, next) => {
// 如果用户访问登录页面,直接放行
if (to.path == '/login') return next()
// 从sessionStorage中获取保存的token值
const tokenStr = window.sessionStorage.getItem('token')
// 没有token,强制跳转到登录页
if (!token) return next('/login')
next()
})
```
退出
基于token的方式实现退出比较简单,只需要销毁本地token即可,这样,后续的请求就不会携带token,必须重新登录生成一个新的token之后才可以访问页面
```js
// 情况token
window.sessionStorage.clear()
// 跳转到登录页
this.$router.push('/login')
```
## 主页布局
通过axios请求拦截器添加token,保证拥有获取数据的权限
```js
// axios请求拦截
axios.interceptors.request.use(config => {
// 为请求头对象添加token验证authorization字段
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
```
## 添加权限管理
> 添加权限管理组件
1. 新建 component/power/Rights.vue
```vue
权限管理
```
2. 配置路由
权限管理业务分析
> 通过全选管理模块控制不同用户可以进行哪些操作,具体可以通过角色的方式进行控制,即每个用户分配一个特定的角色,角色包括不同的功能权限
## 项目优化
- 进度条
```bash
npm install --save nprogress # 运行依赖
```
基于请求展示或隐藏进度条,如果发起了请求,就显示,如果响应了就隐藏,以下是main.js的部分代码
```js
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// axios请求拦截
axios.interceptors.request.use(config => {
NProgress.start()
// 为请求头对象添加token验证authorization字段
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
axios.interceptors.response.use(config => {
NProgress.done()
return config
})
```
- 去除 `console.*`
```bash
npm install babel-plugin-transform-remove-console --save-dev # 属于开发依赖
```
.babel.config.js文件中添加下面代码, 注意,此处是全局配置,无论是dev还是test或prod都会生效
```js
{
"plugins": ["transform-remove-console"]
}
// 或
{
"plugins": [["transform-remove-console", { "exclude": ["error", "warn"] }]]
}
```
- 如何让上述插件只在prod环境生效呢?
修改.babelrc.config.js文件
```js
// 这是项目发布阶段需要用到的babel插件
const prodPlugins = []
if (progress.env.NODE_ENV === 'production') {
// 产品发布环境
prodPlugins.push('transform-remove-console')
}
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
],
// 发布产品时候插件数组
...prodPlugins // 展开赋值
]
}
```
- 生成打包报告
```bash
# 通过vue-cli的命令选项可以生成打包报告
vue-cli-service build --report
# 通过可视化UI面板直接查看报告
```
- 通过vue.config.js修改webpack的默认配置
通过vue-cli工具生成的项目,默认隐藏了所有webpack的配置项,可以参考https://cli.vuejs.org/zh/config/#vue-config-js,自定义配置项
- 为开发模式和发布模式指定不同的打包入口
默认情况下,vue项目的开发模式与发布模式,公用同一个入口文件, src/main.js,为了将项目的开发过程与发布过程分离,我们可以为两种模式,各自指定打包的入口文件,让开发模式入口为src/main-dev.js,发布模式入口为src/main-prod.js
在vue.config.js导出的配置对象中,新增configureWebpack或chainWebpack节点,来自定义webpack的打包配置
参考 https://cli.vuejs.org/zh/guide/webpack.html
以chainWebpack为例
1. 删除src/main.js
2. 添加src/main-dev.js, src/main-prod.js
3. 编辑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')
})
config.when(process.env.NODE_ENV === 'development', config => {
config.entry('app').clear().add('./src/main-dev.js')
})
}
}
```
- 通过externals加载外部CDN资源
默认情况下,通过import语法导入的第三方依赖包,最终都会被打包合并到同一个文件中,从而导致打包成功后,单文件体积过大的问题。通过webpack的externals节点,来配置并加载外部CDN资源,凡是声明在externals中的第三方依赖包,都不会被打包,编辑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')
// 添加externals节点,指定不需要打包的依赖项
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 => {
config.entry('app').clear().add('./src/main.js')
})
}
}
```
同时在main-prod.js中删除相关import导入依赖的语句,然后在public/index.html文件的头部,添加如下的CDN资源引用
```html
```
- 通过CDN优化ElementUI的打包
1. 在main.js中注释掉element-ui按需加载的代码
2. 在index.html的头部区域中,通过CDN加载element-ui的js和css样式
```js
// main.js
// import './plugins/element.js'
```
```html
```
> 为开发模式和发布模式指定不同打包入口
默认情况下,Vue项目的开发模式与发布模式,共用一个打包文件,即src/main.js,为了将项目的开发过程与发布过程分离,我们可以为两种模式,各自指定打包的入口文件,即:
开发模式的入口文件为src/main-dev.js
发布模式的入口文件为src/main-prod.js
```js
// vue.config.js
module.exports = {
chainWebpack: config => {
config.when(process.env.NODE_ENV == 'production', config => {
config.entry('app').clear().add('./src/main-prod.js')
// 通过externals节点加载外部CDN资源
config.set('externals': {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
})
})
config.when(process.env.NODE_ENV == 'development', config => {
config.entry('app').clear().add('./src/main-dev.js')
})
}
}
```
> 通过externals加载外部CDN资源
默认情况下,通过import语法导入的第三方依赖包,最终会被打包合并到同一个文件中,从而导致打包成功后,单文件体积过大。可以通过webpack的externals节点,来配置并加载外部CDN资源,凡是声明在externals中的第三方依赖包,都不会被打包
```js
config.set('externals': {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
})
```
同时,需要在public/index.html文件的头部,添加如下的CDN资源引用
```html
```
> 通过CDN优化Element-UI
在main-prod.js中,注释掉element-ui按需加载的代码
在index.html的头部区域中,通过CDN加载element-ui的js和css样式
```html
```
> 路由懒加载
1. 安装 `@babel/plugin-syntax-dynamic-import` 包
2. 在 `babel.config.js` 配置文件中声明该插件
3. 将路由改为按需加载的形式
```js
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-boo" */ './Baz.vue')
```
网上还有更多简单的懒加载的方法
## 项目上线
> 通过node创建web服务器
创建node项目,并安装express,通过express快速创建web服务器,将vue打包生成的dist文件夹托管为静态资源即可,关键代码如下:
```js
const express = require('express')
const compression = require('compression') // gzip压缩的包
// 创建web服务器
const app = express()
// 启用中间件进行压缩
app.use(compression)
// 托管静态资源
app.use(express.static('./dist'))
// 启动web服务器
app.listen(80, () => {
console.log('web server running at http://127.0.0.1')
})
```
> 开启gzip配置
可以通过服务器端使用Express做gzip压缩,其配置如下
```js
# 安装相应的包
npm install compression -D
// 导入包
const compression = require('compression');
// 启用中间件
app.use(compression)
```
> 配置https
申请SSL证书,https://freessl.org
1. 进入官网,输入要申请的域名并选择品牌
2. 输入自己的邮箱并选择相关选项
3. 验证DNS(在域名管理后台添加TXT记录)
4. 验证通过之后,下载SSL证书(full_chain.pem公钥,private.kety私钥)
5. 配置https,在后台项目中导入证书
```js
const https = require('https')
const fs = require('fs')
const options = {
cert: fs.readFileSync('./full_chain.pem'),
key:fs.readFileSync('./private.key')
}
https.createServer(options, app).listen(443)
```