<p><code></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="背景介绍: 随着项目越来越大,性能问题已经成为了困扰业务发展的重要因素。 功能不停地累加后,核心页面已经不堪重负,访问速度愈来愈慢。 业务发展、用户体验都非常迫切的需要释放页面的负载,提高页面加载速度。 " title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs"><code>背景介绍: 随着项目越来越大,性能问题已经成为了困扰业务发展的重要因素。 功能不停地累加后,核心页面已经不堪重负,访问速度愈来愈慢。 业务发展、用户体验都非常迫切的需要释放页面的负载,提高页面加载速度。 </code></pre> <p>一直在寻找一个优雅的实现前端模块化、并能按权重的优先级顺序异步加载的实现方案。突然了解到<strong>vue的异步组件</strong>,于是便专门研究实践了一下。</p> <hr> <p>首先看一下官网对异步组件的介绍:<br /><span class="img-wrap"><img data-src="/img/remote/1460000012138056?w=1290&amp;h=1188" src="/img/remote/1460000012138056?w=1290&amp;h=1188" alt="异步组件.png" title="异步组件.png" style="cursor: pointer; display: inline;"></span><br />嗯,比较简单的介绍,不过这个特性确实是我眼前一亮,接下来就上代码,看看效果如何:<br />webpack简单设置以及工程结构<br /><span class="img-wrap"><img data-src="/img/remote/1460000012138057?w=1862&amp;h=1570" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="异步组件-工程.png" title="异步组件-工程.png" style="cursor: pointer;"></span><br /><strong>简单的webpack+vue配置</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="var webpack = require('webpack'); module.exports = { watch: true, //监听变化自动编译 entry: { 'index': './src/index.js', }, output: { path: './dist/', filename: '[name].min.js', publicPath:'./dist/' }, module: { loaders: [ { test: /.vue$/, //解析vue模板 loader: &quot;vue-loader&quot; }, { test: /.js$/, //js转换 exclude: /(node_modules)/, loader: &quot;babel-loader&quot;, query: { presets: ['es2015'] } }, { test: /.css$/, //css转换 loader: 'vue-style!css' } ] }, vue: { loaders: { css: 'vue-style!css', } } };" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs typescript"><code><span class="hljs-keyword">var</span> webpack = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack'</span>); <span class="hljs-built_in">module</span>.<a href="http://www.js-code.com/tag/export" title="浏览关于“export”的文章" target="_blank" class="tag_link">export</a>s = { watch: <span class="hljs-literal">true</span>, <span class="hljs-comment">//监听变化自动编译</span> entry: { <span class="hljs-string">'index'</span>: <span class="hljs-string">'./src/index.js'</span>, }, output: { path: <span class="hljs-string">'./dist/'</span>, filename: <span class="hljs-string">'[name].min.js'</span>, publicPath:<span class="hljs-string">'./dist/'</span> }, <span class="hljs-keyword">module</span>: { loaders: [ { test: <span class="hljs-regexp">/.vue$/</span>, <span class="hljs-comment">//解析vue模板</span> loader: <span class="hljs-string">"vue-loader"</span> }, { test: <span class="hljs-regexp">/.js$/</span>, <span class="hljs-comment">//js转换</span> exclude: <span class="hljs-regexp">/(<a href="http://www.js-code.com/tag/node" title="浏览关于“node”的文章" target="_blank" class="tag_link">node</a>_modules)/</span>, loader: <span class="hljs-string">"<a href="http://www.js-code.com/tag/babel" title="浏览关于“babel”的文章" target="_blank" class="tag_link">babel</a>-loader"</span>, query: { presets: [<span class="hljs-string">'es2015'</span>] } }, { test: <span class="hljs-regexp">/.css$/</span>, <span class="hljs-comment">//css转换</span> loader: <span class="hljs-string">'vue-style!css'</span> } ] }, vue: { loaders: { css: <span class="hljs-string">'vue-style!css'</span>, } } };</code></pre> <p><strong>入口js文件:</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="import Vue from 'vue'; import Frame from './index.vue'; let app = new Vue({ el: '#app', render: h => h(Frame),<br /> });" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs typescript"><code><span class="hljs-keyword">import</span> <a href="http://www.js-code.com/tag/vue" title="浏览关于“Vue”的文章" target="_blank" class="tag_link">Vue</a> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>; <span class="hljs-keyword">import</span> Frame <span class="hljs-keyword">from</span> <span class="hljs-string">'./index.vue'</span>; <span class="hljs-keyword"><a href="http://www.js-code.com/tag/let" title="浏览关于“let”的文章" target="_blank" class="tag_link">let</a></span> app = <span class="hljs-keyword">new</span> Vue({ el: <span class="hljs-string">'#app'</span>, render: <span class="hljs-function"><span class="hljs-params">h</span> =&gt;</span> h(Frame), });</code></pre> <p><strong>框架文件:</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<template></p> <div> 异步组件测试<br /> 点击按钮后<br /> 第一个延迟300毫秒,从服务器加载<br /> 第二个不延迟从服务器加载<br /> <template v-if=&quot;show&quot;><br /> <later></later><br /> <later2></later2><br /> </template><br /> <button @click=&quot;toggle&quot;>加载</button> </div> <p></template><br /> <script> import <a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a> from 'vue'; <a href="http://www.js-code.com/tag/const" title="const" target="_blank">const</a> later = <a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>.component('later', function (resolve) { setTimeout(function () { require(['./later.vue'], resolve) }, 3000); }); <a href="http://www.js-code.com/tag/const" title="const" target="_blank">const</a> later2 = Vue.component('later2', function (resolve) { require(['./later2.vue'], resolve) }); <a href="http://www.js-code.com/tag/export" title="export" target="_blank">export</a> default{ data: function () { return { show: false }; }, components: { later, later2, }, created: function () {</p> <p> }, mounted: function () { }, computed: {}, methods: { toggle:function () { <a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>.show = !<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>.show; } }, } </script></p> <style> </style> <p>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name"><a href="http://www.js-code.com/tag/div" title="浏览关于“div”的文章" target="_blank" class="tag_link">div</a></span>&gt;</span> 异步组件测试 点击按钮后 第一个延迟300毫秒,从服务器加载 第二个不延迟从服务器加载 <span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"show"</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">later</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">later</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">later2</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">later2</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"toggle"</span>&gt;</span>加载<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript"> <span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>; <span class="hljs-keyword"><a href="http://www.js-code.com/tag/const" title="浏览关于“const”的文章" target="_blank" class="tag_link">const</a></span> later = Vue.component(<span class="hljs-string">'later'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">resolve</span>) </span>{ setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-built_in">require</span>([<span class="hljs-string">'./later.vue'</span>], resolve) }, <span class="hljs-number">3000</span>); }); <span class="hljs-keyword">const</span> later2 = Vue.component(<span class="hljs-string">'later2'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">resolve</span>) </span>{ <span class="hljs-built_in">require</span>([<span class="hljs-string">'./later2.vue'</span>], resolve) }); <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span>{ <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> { <span class="hljs-attr">show</span>: <span class="hljs-literal">false</span> }; }, <span class="hljs-attr">components</span>: { later, later2, }, <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ }, <span class="hljs-attr">mounted</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ }, <span class="hljs-attr">computed</span>: {}, <span class="hljs-attr">methods</span>: { <span class="hljs-attr">toggle</span>:<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword"><a href="http://www.js-code.com/tag/this" title="浏览关于“this”的文章" target="_blank" class="tag_link">this</a></span>.show = !<span class="hljs-keyword">this</span>.show; } }, } </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="undefined"> </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></code></pre> <p><strong>服务器异步组件1:</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<template></p> <div> load me later 11111 </div> <p></template><br /> <script> <a href="http://www.js-code.com/tag/export" title="export" target="_blank">export</a> default{ data: function () { return {}; }, components: {}, created: function () { }, mounted: function () { }, computed: {}, methods: {}, } </script></p> <style> </style> <p>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span> load me later 11111 <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript"> <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span>{ <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> {}; }, <span class="hljs-attr">components</span>: {}, <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ }, <span class="hljs-attr">mounted</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ }, <span class="hljs-attr">computed</span>: {}, <span class="hljs-attr">methods</span>: {}, } </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="undefined"> </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></code></pre> <p><strong>服务器异步组件2:</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<template></p> <div> load me later 22222 </div> <p></template><br /> <script> export default{ data: function () { return {}; }, components: {}, created: function () { }, mounted: function () { }, computed: {}, methods: {}, } </script></p> <style> </style> <p>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span> load me later 22222 <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript"> <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span>{ <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> {}; }, <span class="hljs-attr">components</span>: {}, <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ }, <span class="hljs-attr">mounted</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ }, <span class="hljs-attr">computed</span>: {}, <span class="hljs-attr">methods</span>: {}, } </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="undefined"> </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span> </code></pre> <hr> <p>好,我们跑起来看看效果!!!</p> <p><strong>1、刷新页面,加载框架</strong><br /><span class="img-wrap"><img data-src="/img/remote/1460000012138058" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="第一步.png" title="第一步.png" style="cursor: pointer;"></span><br /><strong>2、点击加载,此时异步组件2,立刻从服务器加载下来,渲染出来</strong><br /><span class="img-wrap"><img data-src="/img/remote/1460000012138059?w=2338&amp;h=724" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="第二部.png" title="第二部.png" style="cursor: pointer;"></span><br /><strong>3、点击加载后,3000毫秒,此时异步组件1被触发从服务器加载,渲染</strong><br /><span class="img-wrap"><img data-src="/img/remote/1460000012138060?w=2288&amp;h=822" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="第三部.png" title="第三部.png" style="cursor: pointer;"></span></p> <p>利用此特性,我们便能做很多针对前端的优化。<br />比如:将页面核心功能(音、视频播放、文章、商品等等)打包成一个核心模块,通过框架优先加载。<br />其他的一些周边功能打包后,通过服务器异步加载,从而解决业务需求越来越多导致的系统难维护、访问慢问题。</p> <hr> <p>此时,聪明的小伙伴们肯定在想了,既然是异步加载,就会存在加载过程(正在加载中)、以及加载失败等异常情况。<br />这时候怎么办呢,一个个状态去维护吗?No!</p> <p>我们看看官网另一个特性:<br /><span class="img-wrap"><img data-src="/img/remote/1460000012138061?w=1298&amp;h=858" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="高级一部.png" title="高级一部.png" style="cursor: pointer;"></span></p> <p>相信经过上面的使用教程以后,高级异步组件大家一眼就能看懂并会使用,是不是很完美!!!</p> <p>再稍作研究,就准备将它用到实际生产啦。</p> <p></code></p>

本文固定链接: http://www.js-code.com/vue-js/vue-js_26045.html