Vue 异步组件
Posted dm428
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue 异步组件相关的知识,希望对你有一定的参考价值。
最近在做一个 Vue 项目的时候,突然发现了一个有意思的知识点。
有几位客服反馈说在点击某个链接跳转的时候,老是没得反应,导致选不了选项。我就很奇怪,内网环境下是没有问题的,所以代码出问题的可能性不大,怎么外网就有这种问题呢?后来仔细看了一下才发现,原来是运维那边出了点纰漏导致外网有些客户的 javascript 资源加载不出来,进而导致无法跳转。这里涉及到了 Vue 的异步组件知识,只有当切换到某个组件时,其单独打包的资源才会被加载。不同于统一打包的情况,这样做可以利用代码切割减少首屏加载时的资源大小,能够提升一定的加载速度,优化用户体验。接下来就自己重新做一下这个异步组件。
以下命令行操作均在 Linux 环境下进行。
一、搭建项目
先切换到你的项目根目录下,此时应该是一个空文件夹。
然后用 npm 命令初始化,添加具有一些默认选项的 package.json 文件。
$ npm init -y
然后开始创建必要的文件:
$ sudo touch .babelrc index.html
index.html 中写入一下代码,作为固定模板:
<!DOCTYPE html> <html lang="zh-ch"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Async Components</title> </head> <body> <div id="app"></div> </body> </html>
.babelrc 是配置 babel 转译器的,等会再来配置。
接下来创建必要的文件夹:
$ sudo mkdir -p build dist src/components src/routers
在 build 目录下创建三个文件,作为 Webpack 打包的配置文件:
- webpack.base.conf.js
- webpack.dev.conf.js
- webpack.prod.conf.js
然后安装必要的依赖:
$ npm i -D [email protected]7 babel-core babel-preset-env webpack webpack-cli clean-webpack-plugin css-loader html-webpack-plugin vue-loader vue-style-loader vue-template-compiler webpack-dev-server webpack-merge
$ npm i -S vue vue-router
然后把下面的配置代码扔到对应的配置文件中:
// webpack.base.conf.js const path = require(‘path‘); const htmlWebpackPlugin = require(‘html-webpack-plugin‘); const cleanWebpackPlugin = require(‘clean-webpack-plugin‘); const VueLoaderPlugin = require(‘vue-loader/lib/plugin‘); module.exports = { target: ‘web‘, entry: { index: path.resolve(__dirname, ‘../src/index.js‘) }, output: { filename: ‘[name].[hash].js‘, path: path.resolve(__dirname, ‘../dist/‘) }, resolve: { extensions: [‘.vue‘, ‘.js‘, ‘.json‘, ‘.css‘], alias: { ‘@‘: path.resolve(__dirname, ‘../src‘), ‘vue‘: ‘vue/dist/vue.js‘, ‘components‘: path.resolve(__dirname, ‘../src/components‘) } }, node: { fs: ‘empty‘ }, module: { rules: [ { test: /.m?js$/, exclude: /node_modules/, use: ‘babel-loader‘ }, { test: /.css$/, use: [‘vue-style-loader‘, ‘css-loader‘] }, { test: /.vue$/, use: ‘vue-loader‘ } ] }, plugins: [ new htmlWebpackPlugin({ inject: true, template: path.resolve(__dirname, ‘../index.html‘) }), new cleanWebpackPlugin([‘dist‘], { root: path.resolve(__dirname, ‘../‘), verbose: true, dry: false }), new VueLoaderPlugin() ] };
// webpack.dev.conf.js const merge = require(‘webpack-merge‘); const path = require(‘path‘); const baseConfig = require(‘./webpack.base.conf.js‘); module.exports = merge(baseConfig, { mode: ‘development‘, devServer: { contentBase: path.resolve(__dirname, ‘../dist/‘), port: 8888, open: true, // hot: true watchOptions: { watch: true } }, devtool: ‘inline-source-map‘ });
// webpack.prod.conf.js const merge = require(‘webpack-merge‘); const path = require(‘path‘); const baseConfig = require(‘./webpack.base.conf.js‘); module.exports = merge(baseConfig, { mode: ‘production‘, devtool: ‘source-map‘ });
具体怎么配置这里就不赘述了,之前也写过这类型的博客,可以参考一下:基于 Webpack 4 搭建 Vue 开发环境。
然后配置 babel:
在 .babelrc 中写入以下内容:
{ "presets": [ "babel-preset-env" ] }
然后就可以准备开发了。
二、开始 Vue 开发。
在 src 目录下创建一个 index.js 文件作为打包入口文件,然后:
// /src/index.js import Vue from ‘vue‘; import VueRouter from ‘vue-router‘; import App from ‘./App‘; import routerConfig from ‘@/routers‘; Vue.use(VueRouter); const routers = new VueRouter(routerConfig); new Vue({ el: ‘#app‘, components: { App }, router: routers, template: ‘<div><App/></div>‘ });
其中引用了一个同级目录下的 App 作为子组件,App.vue 代码:
<template> <div> <router-view></router-view> <router-link to="/javascript">JavaScript</router-link> <router-link to="/java">Java</router-link> <router-link to="/python">Python</router-link> </div> </template> <script> export default { name: ‘app‘ } </script> <style scoped> h1 { color: blue } </style>
注意到我们的 Vue-Router 配置写在 /src/routers/index.js 中,代码如下:
module.exports = { mode: ‘hash‘, routes: [ { path: ‘/javascript‘, component: (resolve) => {require([‘components/javascript‘], resolve)} }, { path: ‘/java‘, component: (resolve) => {require([‘components/java‘], resolve)} }, { path: ‘/python‘, component: (resolve) => {require([‘components/python‘], resolve)} }, { path: ‘/*‘, redirect: ‘/javascript‘ } ] }
然后在 components 目录下写我们对应的三个组件:
// java.vue <template> <h1>Java</h1> </template> <script> export default { name: ‘java‘ } </script> // javascript.vue <template> <h1>JavaScript</h1> </template> <script> export default { name: ‘javascript‘ } </script> // python.vue <template> <h1>Python</h1> </template> <script> export default { name: ‘python‘ } </script>
修改 npm scripts
npm scripts 的定义如下:
"scripts": { "test": "echo "Error: no test specified" && exit 1", "dev": "webpack-dev-server --config ./build/webpack.dev.conf.js", "build": "webpack --config ./build/webpack.prod.conf.js" },
最后运行起来本地测试服务器:
$ npm run dev
打开浏览器的开发者工具,切换到 Network 选项卡,点击不同的链接,可以看到在加载切换路由时,会加载对应打包出来的 js 资源。
运行 npm run build
,可以看到打包出来了多个 js 资源文件:
总结
-
是一个 Webpack 打包 Vue 项目的优化点,通过异步组件,可以切割我们的代码,提升用户体验。
-
异步组件切割代码实现简单,只需要改变配置 Vue-Router 的方式即可,指定路由对应的组件时,使用如下方式:
{ path: ‘/XXX‘, component: resolve => { require([‘./XXX.vue‘], resolve); } }
以上是关于Vue 异步组件的主要内容,如果未能解决你的问题,请参考以下文章