通过nprogress添加进度条效果
安装nprogress插件:依赖 》安装依赖 》运行依赖,搜索nprogress,安装
配置progress
- 在axios.js中引入NProgress的JS和CSS
- 在axios的request拦截器中,显示进度条NProgress.start()
- 在axios的response拦截器中,隐藏进度条NProgress.done()
import Vue from 'vue'
// 导入axios
import axios from 'axios'
// 导入 NProgress 包对应的JS和CSS
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 设置请求根路径
axios.defaults.baseURL = process.env.VUE_APP_BASE_URL
// axios拦截器
// 在request拦截器中,展示进度条 NProgress.start()
axios.interceptors.request.use(config => {
NProgress.start()
// 在最后必须return config
return config
})
// 在response拦截器中,隐藏进度条 NProgress.done()
axios.interceptors.response.use(config => {
NProgress.done()
return config
})
// 挂载到vue
Vue.prototype.$http = axios
在项目发布阶段移除所有的console
安装插件:依赖 》安装依赖 》开发依赖,搜索babel-plugin-transform-remove-console,安装
在项目中配置,找到项目根目录下babel.config.js文件
// 这是项目发布阶段需要用到的babel插件
const prodPlugins = []
// 如果是production模式,添加插件
if (process.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
]
}
为开发模式与发布模式指定不同的打包入口
默认情况下,Vue项目的开发模式与发布模式,共用同一个打包的入口文件(即main.js)
为了将项目的开发过程和发布过程分离,我们可以为两种模式,各自指定打包的入口文件,即:
- 开发模式入口文件为src/main-dev.js
- 发布模式入口文件为scr/main-prod.js
复制src目录下main.js,copy到src目录下,分别重命名为main-dev.js和main-prod.js
项目根目录下vue.config.js
// 如果有报错,检查一下是不是空格问题导致的
module.exports = {
// 设置打包后输出的目录
outputDir: '../static',
// 设置打包后静态资源目录
assetsDir: 'static',
devServer: {
// 设置自动打开浏览器
open: true,
// 端口号
port: 9999
},
// 打包配置
chainWebpack: config => {
// 开发模式
config.when(process.env.NODE_ENV === 'development', config => {
config.entry('app').clear().add('./src/main-dev.js')
})
// 发布模式
config.when(process.env.NODE_ENV === 'production', config => {
config.entry('app').clear().add('./src/main-prod.js')
})
}
}
通过externals加载外部CDN资源
默认情况下,通过import语法导入的第三方依赖包,最终会被打包合并到同一个文件中,从而导致打包成功后,单文件体积过大问题
为了解决上述问题,可以通过webpack的externals节点,来配置并加载外部的CDN资源,凡是声明在externals中的第三方依赖包,都不会被打包
- 项目根目录vue.config.js中配置
// 如果有报错,检查一下是不是空格问题导致的
module.exports = {
// 设置打包后输出的目录
outputDir: '../static',
// 设置打包后静态资源目录
assetsDir: 'static',
devServer: {
// 设置自动打开浏览器
open: true,
// 端口号
port: 9999
},
// 打包配置
chainWebpack: config => {
// 开发模式
config.when(process.env.NODE_ENV === 'development', config => {
config.entry('app').clear().add('./src/main-dev.js')
})
// 发布模式
config.when(process.env.NODE_ENV === 'production', config => {
config.entry('app').clear().add('./src/main-prod.js')
// 设置加载外部CDN资源,格式-外部资源名:自定义名称
// eg:import NProgress from 'nprogress' 定义为nprogress: 'NProgress'
config.set('externals', {
vue: 'Vue',
vuex: 'Vuex',
// 有中划线,所以加了单引号
'vue-router': 'VueRouter',
// v-charts不知道为啥要反过来写
VCharts: 'v-charts',
echarts: 'echarts',
axios: 'axios',
nprogress: 'NProgress',
moment: 'moment'
})
})
}
}
- 在main-prod中删除外部引入的css
// nprogress的css
import 'nprogress/nprogress.css'
- public目录下index.html中,引入对应版本的css和js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>zhixing.png">
<title>demo</title>
<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- css -->
<link href="https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
<link crossorigin="anonymous" integrity="sha384-+r5wKQwnEAr4Kd2LNn0Ny3mYYBqstQIKUCUAN3lclrC+vPH3Yh31S9csQL+c8j9J"
href="https://lib.baomitu.com/v-charts/1.18.0/style.min.css" rel="stylesheet">
<!-- js -->
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.3/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script src="https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js"></script>
<script src="https://cdn.bootcss.com/echarts/4.7.0/echarts.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.25.3/moment.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.25.3/locale/zh-cn.min.js"></script>
<script crossorigin="anonymous" integrity="sha384-qx5fdRnT7kg5q9TcjgvTUO8JfptIXUXXmMAZlr+kJ8qQoDJ3kLt50dDBfR3F1Lgl"
src="https://lib.baomitu.com/v-charts/1.18.0/index.min.js"></script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
- 对应的依赖版本可以在根目录下package.json中查看
"dependencies": {
"axios": "^0.19.2",
"core-js": "^3.6.4",
"echarts": "^4.7.0",
"element-ui": "^2.4.5",
"moment": "^2.25.3",
"nprogress": "^0.2.0",
"v-charts": "^1.19.0",
"vue": "^2.6.11",
"vue-router": "^3.1.6",
"vuex": "^3.1.3"
}
通过CDN优化ElementUI的打包
- 在main-prod.js中,注释掉element-ui按需加载的代码
// import './plugins/element.js'
- public目录下index.html中,引入对应版本的css和js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>zhixing.png">
<title>demo</title>
<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- css -->
<link href="https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
<link crossorigin="anonymous" integrity="sha384-+r5wKQwnEAr4Kd2LNn0Ny3mYYBqstQIKUCUAN3lclrC+vPH3Yh31S9csQL+c8j9J"
href="https://lib.baomitu.com/v-charts/1.18.0/style.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet">
<!-- js -->
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.3/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script src="https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js"></script>
<script src="https://cdn.bootcss.com/echarts/4.7.0/echarts.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.25.3/moment.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.25.3/locale/zh-cn.min.js"></script>
<script crossorigin="anonymous" integrity="sha384-qx5fdRnT7kg5q9TcjgvTUO8JfptIXUXXmMAZlr+kJ8qQoDJ3kLt50dDBfR3F1Lgl"
src="https://lib.baomitu.com/v-charts/1.18.0/index.min.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.13.0/index.js"></script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
首页内容定制
不同的打包环境下,首页内容可能会有所不同,我们可以通过插件的方式进行定制
- 根目录下vue.config.js
// 如果有报错,检查一下是不是空格问题导致的
module.exports = {
// 设置打包后输出的目录
outputDir: '../static',
// 设置打包后静态资源目录
assetsDir: 'static',
devServer: {
// 设置自动打开浏览器
open: true,
// 端口号
port: 9999
},
// 打包配置
chainWebpack: config => {
// 开发模式
config.when(process.env.NODE_ENV === 'development', config => {
config.entry('app').clear().add('./src/main-dev.js')
// 首页内容定制
config.plugin('html').tap(args => {
// 为args增加一个参数
args[0].isProd = false
return args
})
})
// 发布模式
config.when(process.env.NODE_ENV === 'production', config => {
config.entry('app').clear().add('./src/main-prod.js')
// 设置加载外部CDN资源,格式-外部资源名:自定义名称
// eg:import NProgress from 'nprogress' 定义为nprogress: 'NProgress'
config.set('externals', {
vue: 'Vue',
vuex: 'Vuex',
// 有中划线,所以加了单引号
'vue-router': 'VueRouter',
// v-charts不知道为啥要反过来写
VCharts: 'v-charts',
echarts: 'echarts',
axios: 'axios',
nprogress: 'NProgress',
moment: 'moment'
})
// 首页内容定制
config.plugin('html').tap(args => {
// 为args增加一个参数
args[0].isProd = true
return args
})
})
}
}
- public目录下index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>zhixing.png">
<!-- 首页内容定制 -->
<title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>demo</title>
<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<% if(htmlWebpackPlugin.options.isProd){ %>
<!-- css -->
<link href="https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet">
<link crossorigin="anonymous" integrity="sha384-+r5wKQwnEAr4Kd2LNn0Ny3mYYBqstQIKUCUAN3lclrC+vPH3Yh31S9csQL+c8j9J"
href="https://lib.baomitu.com/v-charts/1.18.0/style.min.css" rel="stylesheet">
<!-- js -->
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.3/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script src="https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js"></script>
<script src="https://cdn.bootcss.com/echarts/4.7.0/echarts.min.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.13.0/index.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.25.3/moment.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.25.3/locale/zh-cn.min.js"></script>
<script crossorigin="anonymous" integrity="sha384-qx5fdRnT7kg5q9TcjgvTUO8JfptIXUXXmMAZlr+kJ8qQoDJ3kLt50dDBfR3F1Lgl"
src="https://lib.baomitu.com/v-charts/1.18.0/index.min.js"></script>
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
路由懒加载
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
路由懒加载:https://router.vuejs.org/zh/guide/advanced/lazy-loading.html
@babel/plugin-syntax-dynamic-import:https://babeljs.io/docs/en/babel-plugin-syntax-dynamic-import/
- 依赖 》安装依赖 》开发依赖,搜索@babel/plugin-syntax-dynamic-impoort,安装
- 根目录下babel.config.js,配置路由懒加载插件
// 这是项目发布阶段需要用到的babel插件
const prodPlugins = []
// 如果是production模式,添加插件
if (process.env.NODE_ENV === 'production') {
prodPlugins.push('transform-remove-console')
}
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
// 发布的时候用到的插件数组
// ... 代表展开运算符,表示把数组展开,放到另一个数组中
...prodPlugins,
// 路由懒加载
'@babel/plugin-syntax-dynamic-import'
]
}
- src目录下,router目录下index.js文件,修改路由
import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入登录组件
const Login = () => import('../components/Login.vue')
// webpackChunkName表示块名称,Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中
// const Login = () => import(/* webpackChunkName: "login" */ '../components/Login.vue')
Vue.use(VueRouter)
const routes = [
// 根路径重定向到登录
{
path: '/',
redirect: '/login'
},
// 登录
{
path: '/login',
component: Login
}
]
const router = new VueRouter({
routes
})
export default router