一、项目搭建
脚手架安装、运行
npm install -g @vue/cli // 全局安装脚手架
vue create my-project // 创建项目
npm i // 项目初始化
npm run serve 或npm run build // 运行起来
vue UI安装、运行
vue ui // 进入项目仪表盘
注意:命令行界面不可以关掉,界面操作时,命令行会响应执行
点击下拉菜单,进入vue项目管理器
点击创建标签页,进入创建项目入口面板
点击下拉菜单,新建文件夹或选择文件夹
点击创建项目
填写项目初始化信息
预设配置
初始功能配置
选择router+使用配置文件+3个默认勾选的,eslint可以去掉,格式检查过于繁琐。
其他配置
选择2.0版本,3.x界面搭建方式正在动手试验中。
url模式选择,选择hash模式
选择语法检查
保存预设并创建项目
创建成功
运行项目
进入任务面板
点击运行
运行成功,打开网页
安装插件和依赖
插件
vue-cli-plugin-element // 插件名称
依赖
分别在vue UI管理器界面搜索以下依赖点击安装
#安装依赖后需要重新编译
axios // 运行依赖
import axios from 'axios';
Vue.prototype.$http = axios;
less loader // 开发依赖
less // 开发依赖 //less loader 依赖于 less
运行依赖和开发依赖区别?
devDependencies 开发依赖
开发依赖是什么,也就是开发中所使用的的依赖,线上生产环境上并不需要他们。
**开发依赖的目的:**是为了减少在安装依赖时node_modules的体积,提升安装依赖的速度,节省线上及其的硬盘资源以及部署上线的时间。
npm i xxx -D // 下同
npm i xxx --save-dev
有哪些开发依赖
dependencies 运行依赖
npm i xxx -S // 下同
npm i xxx --save
插件与依赖的区别?
作用不同
插件也是封装了一系列功能的组件包,但是它是依赖于一个软件环境(这里注意不是运行环境)的,属于软件的一部分功能。
比如vue-cli-plugin-element这个插件就依赖于vue-cli。 它的作用是使这个软件在调用依赖包中的功能时更加的方便,帮助vue-cli修改项目中element的配置。换句话说就是:插件就是帮助软件更好,更方便的使用依赖的。
安装方式不同
vue add @vue/cli-plugin-eslint
二、项目开发
http管理
配置axios请求拦截器+基准地址
开发基准地址
import axios from 'axios'
// 配置请求的根路径
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
// 配置token在请求头中发送:区别在url中发送token
axios.interceptors.request.use(config => {
config.headers.Authorization = window.sessionStorage.getItem('token')
// 在最后必须 return config
return config
})
权限管理
接口权限:token
如果没有token,则不能请求除登录接口之外的接口
#token
获取
登录后获取
保存
window.sessionStorage.setItem('token', res.data.token)
或在vuex中保存(如需缓存token放在了vuex配合本地存储),vuex运行在内存中,关闭应用就会消失,利用本地存储进行中转,下次登录时取出,重新存入vuex中
发送给服务端
在请求头中发送
axios.interceptors.request.use(config => {
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
在url中发送
路由权限:路由守卫
利用token做路由权限控制,如果没有token,则不能通过url进行页面跳转
// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
// to 将要访问的路径
// from 代表从哪个路径跳转而来
// next 是一个函数,表示放行
// next() 放行 next('/login') 强制跳转
if (to.path === '/login') return next()
// 获取token
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login')
next()
})
按钮权限
// 0:不可见 1:不可编辑 2:可编辑
控制可见性
v-if实现按钮的条件渲染
控制可编辑性
按钮标签的:disabled属性
菜单权限
如果后端返回的菜单列表没有某个页面的地址,则无法通过点击的方式进行跳转:通过组件的索引控制跳转的页面
// 页面权限实际上就是菜单权限,如果说我们没有去某个页面的导航菜单,实际上就是没有去那个页面的权限了,所以说页面权限的实际就是菜单权限。
业务功能
登录退出功能
其他功能
前端三基础+组件UI+各路插件进行实现
MQTT功能
1、安装依赖包
npm install mqtt --save
2、项目中引入
import mqtt from 'mqtt'
3、理解MQTT
以区别于请求响应模式的订阅-发布模式进行数据的获取,通过MQTT代理服务器可以作为中间节点,其他客户端或者服务端作为中间节点的连接点,客户端或者服务端都可以进行订阅某个主题,当某个连接点发布了消息,其他订阅了这个主题的节点将会在监听的函数中收到相关消息(数据)。
此时对收到的消息(数据)进行if等判断即可区别不同主题(不同主题类似于不同接口,有一个特定的主码,比如666,代表特定的消息,实际生活的场景如订阅了某前端公众号或某邮箱的某个主题新闻等,一有发布就)就会通知你进行查收,然而,mqtt就是在监听中进行查收的。
三、项目优化、打包、部署
编译模式:开发模式development、生产模式production
项目优化
打包报告生成
// 命令方式生成
vue-cli-service build --report
// 可视化面板中运行生成,如下图
通过externals 加载外部CDN资源
问题
默认情况下,通过import语法导入的第三方依赖包,最终会被打包合并到同一个文件中,从而导致打包成功后,单文件体积 过大的问题。
方法
为了解决上述问题,可以通过webpack的externals节点,来配置并加载外部的CDN资源。凡是声明在externals 中的第三 方依赖包,都不会被打包。
第一步:配置,查看vue.config.js配置文件
第二步:在public/index.html文件的头部,添加CDN资源引用 删除main-prod.js(发布阶段)中对应的import语句
第三步:查看打包结果
第二步:CDN引入方法示例
<head>
<!-- nprogress 的样式表文件 -->
<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/vue-quill-editor@3.0.4/dist/vue-quill-editor.js"> </script>
</head>
第三步:查看CDN加载效果
优化前
优化后
通过CDN加载ElementUI
问题:按需加载被打包进vendors.js
虽然在开发阶段,我们启用了element-ui组件的按需加载,尽可能的减少了打包的体积,但是那些被按需加载的组件,还是 被打包,占用了较大的文件体积。此时,我们可以将element-ui中的组件,也通过CDN的形式来加载,这样能够进—步减小打 包后的文件体积。
方法:
在main-prod.js中,注释掉element-ui按需加载的代码 // import './plugins/element.js'
在index.html的头部区域中,通过cD加载element-ui的js和css样式
<head>
<!-- element-ui 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.8.2/theme-chalk/index.css" />
<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>
</head>
优化前
优化后
按需加载index.html的CDN资源
配置
查看vue.config.js
修改index.html:条件加载
// 条件渲染网页标题
<title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统</title>
// 条件加载CDN
<% if(htmlWebpackPlugin.options.isProd){ %>
// 这里放CDN资源
<% } %>
查看效果
到dist的index.html中查看
开发模式:到浏览器中打开index.html
路由分组懒加载
懒加载:用到的时候才加载,没用到的时候不加载。图片懒加载、组件(路由)懒加载。
路由分组:同一组的被打包到同一个js文件中,加载的时候一起加载,这样所有组件就被切割成多个部分,而不是一次性加载所有组件。
具体需要3步:
安装 代码分割插件 开发依赖
@babel/plugin-syntax-dynamic-import包
配置
查看配置bable.config.js 代码分割插件配置
改造组件import方式
将router.js的组件引入方式改为按需加载引入的形式,即异步组件导入方式+配合代码分割分组
// 这个动态导入会返回一个 `Promise` 对象。
() => import('./my-async-component')
#router.js
// import Login from './components/Login.vue'
const Login = () => import(/* webpackChunkName: "login_home_welcome" */ './components/Login.vue')
// import Home from './components/Home.vue'
const Home = () => import(/* webpackChunkName: "login_home_welcome" */ './components/Home.vue')
// import Welcome from './components/Welcome.vue'
const Welcome = () => import(/* webpackChunkName: "login_home_welcome" */ './components/Welcome.vue')
// import Users from './components/user/Users.vue'
const Users = () => import(/* webpackChunkName: "Users_Rights_Roles" */ './components/user/Users.vue')
// import Rights from './components/power/Rights.vue'
const Rights = () => import(/* webpackChunkName: "Users_Rights_Roles" */ './components/power/Rights.vue')
// import Roles from './components/power/Roles.vue'
const Roles = () => import(/* webpackChunkName: "Users_Rights_Roles" */ './components/power/Roles.vue')
优化前
优化后
项目打包
项目部署
- 后端部署:express(后端)创建服务器并托管为静态资源,监听并启动入口程序,让程序运行在某个端口
- 与后端API程序是两个程序
- 后端优化
- 开启gizip传输压缩
- 压缩前
- 开启gizip传输压缩
-
压缩后
-
开启HTTPS
-
启用PM2
- 问题:命令行启动,复制地址在浏览器打开,关闭命令行,发现页面打不开了。不关闭命令行又难以管理
dist页面空白
module.exports = {
publicPath: './', //配置本地引用目录文件,如不配置,默认为`/`
}
接口请求失败
基准地址需要更改为上线后的的基准地址,而不是局域网的开发地址
三、插件统计
nprogress 进度条
作用:开启请求数据时的进度条
安装
导入main.js
// 导入 NProgress 包对应的JS和CSS
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
配置
axios.interceptors.request.use(config => {
// console.log(config)
NProgress.start()
// 在最后必须 return config
return config
})
// 在 response 拦截器中,隐藏进度条 NProgress.done()
axios.interceptors.response.use(config => {
NProgress.done()
return config
})
babel-p1ugin-transform-remove-console 调试语句消除
问题
当vue-cli在ui界面任务下进行build生成生产环境代码时,如果碰到有console类型的语句,是会报错的。
作用
消除开发阶段调试使用的console.log语句
安装
npm install babel-plugin-transform-remove-console --save-dev
或vue ui图形界面中中搜索开发依赖进行安装
配置
.babelrc(官方推荐)
查看babel.config.js配置文件代码、注释(vue对应的配置文件)
使用方法
构建项目时自动生效,打开浏览器调试台,可以查看效果
Prettier - Code formatter 格式化代码
安装
配置
.prettierrc中进行配置编辑器格式化
四、配置文件
.prettierrc vsCode格式化配置文件
配置:调整编辑器代码格式化
{
"semi": false, // 关闭分号
"singleQuote": true, // 引号格式化为单引号
"printWidth": 200 // 代码多宽换行
}
![](static/image-20210306170224399.png
.eslintrc.js 格式检查配置文件
配置:取消检查函数括号前空格
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'@vue/standard'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// 配置不检查函数前的空格
'space-before-function-paren': 0
},
parserOptions: {
parser: 'babel-eslint'
}
}
babel.config.js 插件配置
配置:发布阶段移除console
// transform-remove-console固定配置:对比下个代码块的动态判断配置
// 缺点:开发阶段 、生产阶段都会移除console.log(),不符合预期的需求,需求只需要移除生产阶段的console就OK
module.exports = {
presets: ['@vue/app'],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
],
// 新增的代码:插入一个插件数组即可对插件配置成功
['transform-remove-console']
'@babel/plugin-syntax-dynamic-import'
]
}
// transform-remove-console动态判断配置
// 生产(发布)阶段需要用到的 babel 插件
const prodPlugins = []
// 是否是生产阶段
if (process.env.NODE_ENV === 'production') {
// 构建一个数组,在plugins节点中插入
prodPlugins.push('transform-remove-console')
}
module.exports = {
presets: ['@vue/app'],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
],
// 展开发布产品时候的插件数组
...prodPlugins,
'@babel/plugin-syntax-dynamic-import'
]
}
配置代码分割插件
module.exports = {
plugins: [
[
],
// 与其他配置的数组同一级
'@babel/plugin-syntax-dynamic-import'
]
}
vue.config.js webpack打包配置
通过vue-cli 3.0工具生成的项目,默认隐藏了所有webpack的配置项,目的是为了屏蔽项目的配置过程,让程序员把工作的重心,放到具体功能和业务逻辑的实现上。配置文档
在vue.configjs 导出的配置对象中,新增configureWebpack或chainWebpack 节点,来自定义webpack的打包配置。
在这里, configureWebpack和chainWebpack的作用相同,唯一的区别就是它们修改webpack配置的方式不同: chainWebpack通过链式编程的形式,来修改默认的webpack配置configureWebpack通过操作对象的形式,来修改默认的webpack配置
配置:分离开发模式和发布模式打包入口(省略配置baseUrl)
配置
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')
})
}
}
创建
src/main-dev.js
src/main-prod.js
配置:第三方依赖采用CDN加载
module.exports = {
chainWebpack: config => {
// 发布模式
config.when(process.env.NODE_ENV === 'production', config => {
// 配置取消第三方依赖进行打包成vendors.js
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 => {
// 其他配置
})
}
}
配置:配置CDN资源按需加载,开发模式不需要
module.exports = {
chainWebpack: (config) => {
// 发布模式
config.when(process.env.NODE_ENV === 'production', (config) => {
// 开发模式下返回生产模式的flag
config.plugin('html').tap((args) => {
args[0].isProd = true
return args
})
})
// 开发模式
config.when(process.env.NODE_ENV === 'development', (config) => {
// 开发模式下返回不是生产模式的flag
config.plugin('html').tap((args) => {
args[0].isProd = false
return args
})
})
},
}
五、代码段复用
配置性的代码段
// 判断vue项目的编译模式是处于开发模式或生产模式
process.env.NODE_ENV === 'development'
process.env.NODE_ENV === 'production'
本文提供了一个项目复盘的思路,进行了全面的解剖,我个人认为是有挺大参考价值的,当我们完成了某项计划和行动,复盘可以理清思路,让表达更加清晰。
转载请联系作者授权并放上小小的一条链接~
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: Mindos__全掘金的最靓的仔 原文链接:https://juejin.im/post/6939479680269418526