# myFrist **Repository Path**: xiaozichen/myFrist ## Basic Information - **Project Name**: myFrist - **Description**: 第一个vue项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2019-09-23 - **Last Updated**: 2024-11-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Vue.js 及实战项目 > node.js 设计模式是 MVC. > Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层. #### (1).历史介绍 angular 09年,年份较早,一开始大家是拒绝 star; react 2013年,用户体验好,直接拉到一堆粉丝 star;(Facebook) vue 2014年,用户体验好 star.(尤玉溪) #### (2).前段框架与库的区别 - jQuery 库 -> DOM(操作 DOM) + 请求 - art-template 库 -> 模板引擎 - 框架 = 全方位功能齐全 - 框架 = 全方位功能齐全 - 简易的 DOM 体验 + 发请求 + 模板引擎 + 路由功能 - KFC 的世界里,库就是一个小套餐,框架就是全家桶 - 代码上的不同 - 一般使用库的代码,是调用某个函数,自己把控库的代码 - 一般使用框架,其框架在帮助运行写好的代码 - 框架:初始化自身的一些行为 - 执行所编写的代码 - 施放一些资源 #### (3).vue 起步 - 1.引包 - 2.启动 new Vue({el:目的地,template:模板内容}); - 3.options - 目的地 el - 内容 template - 数据 data 保存数据属性 - 数据驱动视图 ``` MVC 设计模式:M(Model-数据模型) V(View-视图) C(Controller-控制器) 数据不是主动的到视图上的,它是靠控制器取到 Model 展示到 View Vue 只关注的是视图层,设计模式是 MVVM:M(Model-数据模型) V(View-视图) VM(ViewModel-同步视图和数据的对象) ``` #### (4).插值表达式 - {{ 表达式 }} - 对象(不要连续3个 ``` {{ { name:'jack' } }} ```) - 字符串 ``` {{'xxx'}} ``` - 判断后的布尔值 ``` {{ true }} ``` - 三元表达式 ``` {{ true?'正确':'错误' }} ``` - 可以用于页面中简单粗暴的调试 - 注意:必须在 data 这个函数中返回的对象中声明 #### (5).指令 - 在 vue 中提供了一些对于页面 + 数据的更为方便的输出,这些操作就叫做指令,以 ``` v-xxx ``` 表示 - 比如 html 页面中的属性 ``` `
` ``` - 比如在 angular 中以 ``` ng-xxx ``` 开头的就叫做指令 - 在 vue 中以 ``` v-xxx ``` 开头的就叫做指令 - 指令中封装了一些 DOM 行为,结合属性作为一个暗号,暗号有对应的值,根据不同的值,框架会进行相关 DOM 操作的绑定 #### (6).vue 中常用的 v- 指令演示 - v-text: 元素的 innerText 属性,必须是双标签,跟 ``` {{}} ``` 效果是一样的,使用极少 - v-html: 元素的 innerHTML - v-if: 判断是否插入这个元素,相当于对元素的销毁和创建 - v-else-if - v-else - v-show: 隐藏元素,如果确定要隐藏,会给元素的 style 加上 display:none.是基于 css 样式的切换 ``` v-text 只能用在双标签中 v-text 其实就是给元素的 innerText 赋值 v-html 其实就是给元素的 innerHTML 赋值 v-if 如果值为 false,会留下一个 作为标记,万一未来 v-if 的值是 true 了,就在这里插入元素 如果有 if 和 else 就不需要单独留坑了 如果全用上 v-if 相邻 v-else-if 相邻 v-else 否则 v-else-if 可以不用 v-if 和 v-else-if 都有等于对应的值,而 v-else 直接写 v-if 家族都是对元素进行插入和移除的操作 v-show 是显示与否的问题 注意:指令其实就是利用属性作为标识符,简化 DOM 操作 例:v-model='xxx' -> v-model 代表要做什么,xxx 代表针对的 js 内存对象 -> 写在哪个元素上,就对哪个元素操作 ``` #### (7).v-if 和 v-show 的区别 v-if 是"真正"的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建 v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做 ———— 直到条件第一次变为真时,才会开始渲染条件块 相比之下,v-show 就简单得多 ———— 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好 ## webpack > 里面主要是 webpack 3.x 版本的讲解 > webpack 是一个现代 JavaScript 应用程序的静态模块打包器.当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle. ![webpack的图片](https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=321999652,1157447012&fm=26&gp=0.jpg) #### 历史介绍 - 2009年初,commonjs 规范还未出来,此时前段开发人员编写的代码都是非模块化的 - 那个时候开发人员经常需要十分留意文件加载顺序所带来的依赖问题 - 与此同时 nodejs 开启了 js 全栈大门,而 requirejs 在国外也带动着前端逐步实现模块化 - 同时国内 seajs 也进行了大力推广 - AMD 规范,具体实现是 requirejs define('模块 id',[模块依赖1, 模块依赖2],function(){ return ; }),ajax 请求文件并加载 - Commonjs || CMD 规范 seajs 淘宝玉伯 - commonjs 和 cmd 非常相似的 - cmd require/module.exports - commonjs 是 js 在后端语言的规范:模块、文件操作、操作系统底层 - CMD 仅仅是模块定义 - UMD 通用模块定义,一种既能兼容 amd 也能兼容 commonjs 也能兼容浏览器环境运行的万能代码 - npm/bower 集中包管理的方式备受青睐,12年 browserify/webpack 诞生 - npm 是可以下载前后端的 js 代码 475000 个包 - bower 只能下载前端的 js 代码,bower 在下载 bootstrap 的时候会自动的下载 jquery - browserify 解决让 require 可以运行在浏览器,分析 require 的关系、组装代码 - webpack 打包工具,占市场主流 ``` (function (root, factory){ if(typeof exports === 'object'){ module.exports = factory(); //commonjs 环境下能拿到返回值 }else if(typeof exports === 'function'){ define(factory); //define(function(){return 'a'}) AMD }else{ window.eventUtil = factory(); } })(this, function(){ // module return { //具体模块代码 addEvent:function(el, type, handle){ //... }, removeEvent:function(el, type,handle){ }, }; }); ``` #### 模块实现 1. 下载 webpack 为项目开发依赖 ``` //在项目中搭建 webpack npm init npm install webpack --save-dev // 高版本中需要手动在 package.json 需要修改添加 // "scripts": { // "test": "echo \"Error: no test specified\" && exit 1", // "dev": "webpack --mode development", // "build": "webpack --mode production" // } // 使用打包单文件需要输入命令 webpack main.js -o build.js(高版本) 或 webpack ./main.js ./build.js(低版本) ``` 2. 创建 main.js 作为项目的入口文件 ``` //整个程序的入口文件 import Vue from './Vue.js' import Vue from './App.js' //模块整体加载 //import {num, num2, add} from './App.js' //console.log(num) //console.log(num2) //add(3, 5) //import * as object from './App.js' //console.log(object) //console.log(object.num) //console.log(object.num2) //add(3, 5) new Vue({ el:'#app', components:{ App }, template:`` }) ``` 3. 创建一个 App.js ``` var app = { template:`
我是一个入口组件
` } //声明并导出 export var num1 = 2; //作为一整个对象 key 导出 // 声明再导出 var num2 = 3 export{ num2 } export function add(x,y){ return x+y } export default app; ``` 4. 在 package.json 文件中配置如下: ``` { "name": "webpackDemo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --mode development", "build": "webpack --mode production" }, "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.34.0" } } ``` 5. 新建一个 index.html,script 脚本引入打包完成的 build.js 如下: ``` webpack
``` #### webpack 编译之后的 build 文件解读 ##### webpack 打包模块的源码执行顺序 - 1.把所有模块的代码放入到函数中,用一个数组保存起来 - 2.根据 require 时传入的数组索引,能知道需要哪一段代码 - 3.从数组中,根据索引取出包含我们代码的函数 - 4.执行该函数,传入一个对象 module.exports - 5.我们的代码,按照约定,正好是用 module.exports = 'xxx' 进行赋值 - 6.调用函数结束后,module.exports 从原来的空对象,就有值了 - 7.最终 return module.exports;作为 require 函数的返回值 #### css 文件处理 ##### es6 模块导入 ``` import './main.css' ``` 对于 webpack 来说,css 文件也是一个模块,但是像这样的文件,webpack 得需要 loaders 去处理这些文件. 下载并配置 ``` npm i css-loader style-loader -D module:{ rules:[ { //遇到后缀为 .css 的文件,webpack 先用 css-loader 加载器去解析这个文件 //最后计算完的 css,将会使用 style-loader 生成一个内容为最终解析完的 css 代码的 style 标签,放到 head 标签里. //webpack 在打包过程中,遇到后缀为 css 的文件,就会使用 style-loader 和 css-loader 去加载这个文件 test:/\.css$/, loader:'style-loader!css-loader' } ] } ``` #### 图片文件的处理 App.js 导入图片资源 ``` import imgSrc from './yx.png' export default{ template:`
`, data(){ return { imgSrc: imgSrc } } } ``` 对文件的处理,webpack 得需要 ``` url-loader ``` 和 ``` file-loader ``` 下载处理图片的 loader 模块 ``` npm i url-loader file-loader -D ``` 添加 loader 的配置 ``` module:{ rules:[ { test:/\.css$/,//支持正则 loader:'style-loader!css-loader' }, { test:/\.(jpg|png|jpeg|gif|svg)$/, loader:'url-loader?limit=200' } ] }, ``` ``` webpack 最终会将各个模块打包成一个文件,因此我们样式中的 url 路径是相对入口 html 页面的,而不是相对于原始 css 文件所在的路径的.这就会导致图片引入失败.这个问题是用 file-loader 可以解析项目中的 url 引入(不仅限于 css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引入路径,使之指向正确的文件. 简易,对于图片的大小小于 limit 设置的大小的图片,使用 base64 编码,可以减少一次图片的网络请求;那么对于比较大的图片,使用 base64 就不适合了,编码会和 html 混在一起,一方面可读性差,另一方面加大了 html 页面的大小,反而加大了下载页面的大小,得不偿失了呢,因此设置一个合理的 limit 是非常有必要的. ``` #### webpack-dev-server ##### 下载模块 ``` npm install webpack-dev-server --save-dev ``` 常用配置参数 --open 自动打开浏览器 --hot 热更新,不在刷新的情况下替换 css 样式 --inline 自动刷新 --port 指定端口 --process 显示编译进度 在 package.json 文件中配置 ``` "main": "index.js", "script":{ "dev":"webpack-dev-server --open --hot --inline --config ./webpack.dev.config.js", "prod":"webpack --config ./webpack.prod.config.js" }, "keywords":[], "author":"" ``` 直接执行 ``` npm run dev ``` #### es6 的解析 ##### 模块介绍 ``` babel-core: ``` ``` javascript babel-core 的作用是把 js 代码分析成 ast(抽象语法树),方便各个插件分析语法进行相应的处理.有些新语法在低版本 js 是不存在的,如箭头函数,rest 参数,函数默认值等,这种语言层面的不兼容只能通过将代码转为 ast,分析其语法后再转为低版本 js ``` abel 转译器本身,提供了 babel 的转译 API,如 babel.transform 等,用于对代码进行转译.像 webpack 的 babel-loader 就是调用这些 API 来完成转译过程的. ``` babel-loader: ``` 在将 es6 的代码 transform 进行转译,就是通过 babel-loader 来完成. ``` babel-preset-env ``` 如果要自行配置转译过程中使用的各类插件,那太痛苦了,所以 babel 官方帮我们做了一些预设的插件集,称之为 preser,这样我们只需要使用对应的 preset 就可以了.以 js 标准为例,babel 提供了如下的一些 preset: - es2015 - es2016 - es2017 - env es20xx 的 preset 只转译该年份批准的标准,而 env 则代指最新的标准,包括了 latest 和 es20xx 各年份,另外,还有 stage-0 到 stage-4 的标准成形之前的各个阶段,这些都是实验版的 preset,建议不要使用. ``` babel-plugin-transform-runtime ``` Babel 默认只转换新的 JavaScript 语法,而不转换新的 API.例如,Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Peomise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转译.如果想使用这些新的对象和方法,必须使用 babel-polyfill,为当前环境提供一个垫片. [babel的polyfill和runtime的区别](https://segmentfault.com/q/1010000005596587?from=singlemessage&isappinstalled=1) ##### 安装模块 ``` npm install babel-core babel-loader babel-preset-env babel-plugin-transform-runtime -D ``` ##### 在 webpack.dev.config.js 配置 ``` rules:[ { //处理 es6,7,8 test:/\.js$/, loader:'babel-loader', exclude:/node_modules/, //node_modules目录下的文件除外 options:{ presets:['env'], //处理关键字 plugins:['transform-runtime'], //处理函数 } } ] ``` #### 单文件引入 ##### 下载包 ``` npm install vue-loader@14.1.1 vue-template-compiler@2.5.17 -D ``` ##### 创建 App.vue 文件 ``` //组件的模板结构 //组件的业务逻辑 //组件的样式 ``` ##### 创建入口文件 main.js ``` import Vue from 'vue'; import App from './App' new Vue({ el:'#app', //Render 函数是 Vue2.x 版本新增的一个函数; //使用虚拟 dom 来渲染节点提升性能,因为它是基于 JavaScript 计算. //通过使用 createElement(h) 来创建 dom 节点.createElement 是 render 的核心方法.其 Vue 编译的时候会把 template 里面的节点解析成虚拟 dom; render:c=>c(APP) //components:{ // App //}, //template:`` }) ``` ##### webpack.dev.config.js 文件配置 ``` //处理 Vue 文件 { test:'/\.vue$/', loader:'vue-loader' } ``` #### CommonsChunkPlugin 的使用 (3.x) > CommonsChunkPlugin 主要是用来提取第三方库和公共模块,避免首屏加载的 bundle 文件或者按需加载的 bundle 文件体积过大,从而导致加载时间过长,着实是优化的一把利器. ##### chunk 的分类 - webpack 当中配置的入口文件(entry)是 chunk,可以理解为 entry chunk - 入口文件以及它的依赖文件通过 code splite(代码分割)出来的也是 chunk,可以理解为 children chunk - 通过 CommonsChunkPlugin 创建出来的文件也是 chunk,可以理解为 commons chunk ##### CommonsChunkPlugin 可配置的属性 [参看资料](https://segmentfault.com/a/1190000018218985) - name:可以是已经存在的 chunk(一般指入口文件)对应的 name,那么就会把公共模块代码合并到这个 chunk 上;否则,会创建名字为 name 的 commons chunk 进行合并 - filename:指定 commons chunk 的文件名 - chunks:指定 source chunk,即指定从哪些 chunk 当中去找公共模块,省略该选项的时候,默认就是 entry chunks - minChunks:既可以是数字,也可以是函数,还可以是 Infinity ##### 验证三种情况 - 不分离出第三方库和自定义公共模块 - 分离出第三方库、自定义公共模块、webpack 运行文件,但它们在同一个文件中 - 单独分离第三方库、自定义公共模块、webpack 运行文件,各自在不同文件 1. 不分离出第三方库和自定义公共模块 src 目录下各个文件内容,尽量保持简单,方便理解 ``` --common.js export const common = 'common file'; --main1.js export {common} from './common.js'; import Vue from 'vue' console.log(Vue, 'main1${common}'); --main2.js import {common} from './common.js' import Vue from 'vue' console.log(Vue,'main2${common}') ``` webpack.config.js ``` const path = require('path') module.exports = { //入口 entry:{ //可以有多个入口,也可以有一个,如果有一个就默认从这一个入口开始分析 'main1':'./src/main1.js', 'main2':'./src/main2.js' }, output:{ path:path.resolve('./dist'), //相对转绝对 fileanme:'[name].js' }, watch:true, //文件监视改动,自动产出 build.js } ``` 问题:查看 main1.js 和 main2.js,会发现共同引用的 common.js 文件和 Vue 都被打包进去了,这肯定不合理,公共模块重复打包,体积过大. 2. 分离出第三方库、自定义公共模块、webpack 运行文件 修改 webpack.config.js 新增一个入口文件 vendor 和 CommonsChunkPlugin 插件进行公共模块的提取: ``` const path = require('path'); const webpack = require('webpack'); const packagejson = require('./package.json'); module.exports = { //入口 entry:{ 'main1':'./src/main1.js', 'main2':'./src/main2.js', 'vendor':Object.keys(packagejson.dependencies) //获取生产环境依赖的库 }, //出口 output:{ path: path.resolve('./dist'), //相对转绝对 fileanem: '[name].js' }, watch:true, //文件监视改动 自动产出文件 //webpack 3.x 的写法 //plugins:[ // new webpack.optimize.CommonsChunkPlugin({ // name:['vendor'], // filename:'[name].js' // }) //] //webpack 4.x 的写法 optimization: { // 分割代码块 splitChunks: { cacheGroups: { //公用模块抽离 common: { chunks: 'all', minSize: 0, //大于0个字节 minChunks: 2 //抽离公共代码时,这个代码块最小被引用的次数 } } } } } ``` 查看 dist 目录,新增了一个 vendor.js 文件 通过查看 vendor.js 文件,发现 main1.js 和 main2.js 文件中依赖的 vue 和 common.js 都被打包进 vendor.js 中,同时还有 webpack 的运行文件.总的来说,我们初步的目的达到,提取公共模块,但是它们都在同一个文件中. 到这里,肯定有人希望自家的 vendor.js 纯白无瑕,只包含第三方库,不包含自定义的公共模块和 webpack 运行文件,又或者希望包含第三方库和公共模块,不包含 webpack 运行文件. 其实,这种想法是对的,特别是分离出 webpack 运行文件,因为每次打包 webpack 运行文件都会变,如果你不分离出 webpack 运行文件,每次打包生成 vender.js 对应的哈希值都会变化,导致 vendor.js 改变,但实际上你的第三方库其实是没有变,然而浏览器会认为你原来缓存的 vendor.js 就失效,要重新去服务器中获取,其实只是 webpack 运行文件变化而已,就要人家重新加载,好冤呀~ 3. 单独分离出第三方库、自定义公共模块、webpack 运行文件 这里分两步走: (1)先单独抽离出 webpack 运行文件 (2)接着单独抽离第三方库和自定义公共模块 (1)抽离 webpack 的运行文件 修改 webpack 的配置文件 ``` //webpack 3.x 的写法 plugins:[ new webpack.optimize.CommonsChunkPlugin({ name:['vendor', 'runtime'], filename:'[name].js' }) ] //其实上面这段代码,等价于下面这段 plugins:[ new webpack.optimize.CommonsChunkPlugin({ name:'vendor', filename:'[name].js' }), new webpack.optimize.CommonsChunkPlugin({ name:'runtime', filename:'[name].js', chunks:['vendor'] }) ] ``` 上面两段抽离 webpack 运行文件代码的意思是创建一个名为 runtime 的 commons chunk 进行 webpack 运行文件的抽离,其中 source chunks 是 vendor.js. 查看 dist 目录下,新增了一个 runtime.js 的文件,其实就是 webpack 的运行文件 再来查看一下命令行中 webpack 的打包信息,就会发现 vendor.js 的体积已经减小,说明已经把 webpack 运行文件提取出来了 可是,vendor.js 中还有自定义的公共模块 common.js,人家只想 vendor.js 拥有项目依赖的第三方库而已(这里是 jqurey),这个时候把 minChunks 这个属性引进来. minChunks 可以设置为数字、函数和 Infinity,默认值是 2,并不是官方文档说的入口文件的数量,下面解释下 minChunks 的含义: - 数字:模块被多少个 chunk 公共引用才被抽离出来成为 commons chunk - 函数:接受(module, count)两个参数,返回一个布尔值,你可以在函数内进行你规定好的逻辑来决定某个模块是否提取成为 commons chunk - Infinity:只有当入口文件 (entry chunks) >=3 才生效,用来在第三方库中分离自定义的公共模块 (2)抽离第三方库和自定义公共模块 minChunks 设为 Infinity,修改 webpack 配置文件如下: ``` plugins:[ new webpack.optimize.CommonsChunkPlugin({ name:['vendor', 'runtime'], filename:'[name].js', minChunks: Infinity }), new webpack.optimize.CommonsChunkPlugin({ name:'common', filename:'[name].js', chunks:['main1', 'main2'] //从 first.js 和 second.js 中抽取 commons chunk }) ] ``` 在来查看一下命令行中 webpack 的打包信息,自定义的公共模块分离出来: 这时候的 vendor.js 就纯白无瑕,只包含第三方库文件,common.js 就是自定义的公共模块,runtime.js 就是 webpack 的运行文件. #### [webpack 4.x 抽离公共组件](https://segmentfault.com/a/1190000018218985) 在开发多个页面的项目的时候,有时候会在几个页面中引用某个公共的模块,这些公共模块多次被下载会造成资源浪费,如果把这些公共模块抽离出来只需下载一次之后便缓存起来了,这样就可以避免因重复下载而浪费资源,那么怎么在webpack中抽离出公共部分呢?方法如下: (1) 公共模块抽离 配置 webpack.config.js 文件 ``` module.exports = { //... //优化项配置 optimization: { // 分割代码块 splitChunks: { cacheGroups: { //公用模块抽离 common: { chunks: 'initial', minSize: 0, //大于0个字节 minChunks: 2 //抽离公共代码时,这个代码块最小被引用的次数 } } } } } ``` (2)第三方模块抽离 页面中有时会引入第三方模块,比如import $ from 'jquery'; page1中需要引用,page2中也需要引用,这时候就可以用vendor把jquery抽离出来,方法如下: ``` module.exports = { //... //优化项配置 optimization: { // 分割代码块 splitChunks: { cacheGroups: { //公用模块抽离 common: { chunks: 'initial', minSize: 0, //大于0个字节 minChunks: 2, //在分割之前,这个代码块最小应该被引用的次数 }, //第三方库抽离 vendor: { priority: 1, //权重 test: /node_modules/, chunks: 'initial', minSize: 0, //大于0个字节 minChunks: 2, //在分割之前,这个代码块最小应该被引用的次数 } } } } } ``` 注意:这里需要配置权重 priority,因为抽离的时候会执行第一个common配置,入口处看到jquery也被公用了就一起抽离了,不会再执行wendor的配置了,所以加了权重之后会先抽离第三方模块,然后再抽离公共common的,这样就实现了第三方和公用的都被抽离了。 不加权重之前: jquery也被抽离到了公共js里 ![webpack 的解析文件](https://segmentfault.com/img/bVboBHn?w=1202&h=410) 加了权重之后: ![webpack 的解析文件](https://segmentfault.com/img/bVboBKv?w=1040&h=462) #### webpack 异步加载的原理 webpack ensure 有人称它为异步加载,也有人说做代码切割.其实说白了,它就是把 js 模块给独立导出一个 .js 文件的,然后使用这个模块的时候,webpack 会构造 script dom 元素,由浏览器发起异步请求这个 js 文件. webpack.ensure 的原理: 它就是**把一些 js 模块给独立出一个个 js 文件,然后需要用到的时候,在创建一个 script 对象,加入到 document.head 对象中即可**,浏览器会自动帮我们发起请求,去请求这个 js 文件,在写个回调,去定义得到这个 js 文件后,需要做什么业务逻辑操作. main.js 依赖三个 js - A.js 是封装 aBtn 按钮点击后,才执行的业务逻辑 - B.js 是封装 bBtn 按钮点击后,才执行的业务逻辑 - vue.js 是封装了 main.js 需要利用的包 针对上面的需求,**优化方案** 假设 A.js B.js Vue.js 都是非常大的文件,因为 A.js B.js 都不是 main.js 必须有的,即未来可能发生的操作,那么我们把他们利用异步加载,当发生的时候再去加载就行了 vue.js 是 main.js 立即马上依赖的工具箱.但是它又非常的大,所以将其配置打包成一个公共模块,利用浏览器的并发加载,加快下载速度.ok,构思完成,开始实现.