摘要:异步组件我接触的也不多,在Vue-router中有过接触,它的意思是这样的:假如有几个路由组件“用户管理“、”系统配置“、”任务管理“,我们知道在中一次只显示一个组件,那么在初始页面时,我们可以只加载一个,后面两个可以在需要的时候再加
提示:后面有完整的调试代码,可以先运行观察结果,再配合文章。
这篇解决异步组件的问题。
异步组件我接触的也不多,在Vue-router中有过接触,它的意思是这样的:假如有几个路由组件“用户管理“、”系统配置“、”任务管理“,我们知道在中一次只显示一个组件,那么在初始页面时,我们可以只加载一个,后面两个可以在需要的时候再加载,这就是所谓的懒加载,也就是异步加载组件,图示如下:
这个建议是能接受的,假如前端有几十个这样的组件,可以提升很多性能。
工厂函数就是Vue规定的生产异步组件的一个函数,图示如下:
可以看到,异步组件的定义是一个工厂函数。假如我们要显示这个异步组件,它要经过两次渲染,为什么呢?因为它是异步的,举个例子,比如A要B帮他做作业,流程如下:
第一次:A找到B,由于是异步的,B的作业没做完。那么A什么都没拿到,A就会想我不能这样跑了,因为B什么时候做完作业是未知的,那么他就会给B留下一个手机号(钩子),等做完之后B打电话通知他。
A在等待中....
第二次:B做完作业,打电话通知A,A过来拿作业。
这个简例就是Vue两次渲染的过程。
resolve就是Vue准备的钩子,第一次渲染时调用函数,想拿到异步组件结果扑个空,因为异步组件还有1秒才能加载过来,因此它就留下一个钩子resolve,意思是说如果组件加载好了,就把它塞到我的钩子里面。等到拿到结果之后,Vue在钩子函数resolve内部开始第二次渲染,将异步组件显示出来,这就是两次渲染的流程。
理解了原理,我们就明白了工厂函数不管怎么写都无所谓,反正只要把最后产出的组件塞到resolve里面就可以了。
下面我们看下工厂函数的三种形式。
代码如下:
components: {'async-component': function (resolve) {//模拟延迟setTimeout(function {//...请求中resolve(MyComponent)},1000)}}分析:这种是容易理解的方式,只要在里面执行resolve传入组件就可以了。
components: {'async-component': function {return new Promise(resolve => {//模拟延迟setTimeout(function {resolve(MyComponent)},1000)})}}分析:这次不一样了,工厂函数返回一个Promise对象,而且这个定义里面也没有看到Vue提供的钩子,那么实际上Vue就将钩子添加到该Promise的回调中,即:
//钩子注到promise的回调中(...Promise实例).then(resolve);这样也可以达到目标。
为什么要返回一个对象呢?因为Vue考虑到,假如这个组件加载很久,我们是不是可以提前先渲染一个loading...的组件,这样用户体验感会好些。
代码如下:
Vue.component('async-component', => ({component: new Promise((resolve) => {setTimeout( => resolve(MyComponent), 1000);}),loading: {template: '加载中...'},error: {template: '加载失败,请重试'},delay: 300,timeout: 2000}));分析:这个Lambda函数返回一个对象,主要有五部分组成:
delay表示多久之后loading开始加载,一般设置200-300ms左右。假如delay设置的时间比异步组件加载的时间还长,那么loading就不会渲染。
加载组件const MyComponent = {template: '✅ 全局异步组件加载成功!'};Vue.component('async-component', => ({component: new Promise((resolve) => {setTimeout( => resolve(MyComponent), 1000);}),loading: {template: '加载中...'},error: {template: '加载失败,请重试'},delay: 300,timeout: 2000}));Vue.component('childComponent',{template: `子组件中的异步组件:
`,props: ['show']})new Vue({el: '#app',data {return {show: false};}});来源:恋爱脑一点号