Vue动态组件和异步组件原理详解


Posted in Javascript onMay 06, 2019

前言

在vue官方资料中,我们可以可以很学会如何通过vue构建“动态组件”以及“异步组件”,然而,在官方资料中,并没有涉及到真正的“动态异步”组件,经过大量的时间研究和技术分析,我们给出目前比较合理的技术实现方式,并分析一下vue动态异步组件的原理

动态组件 & 异步组件的存在,使得我们更方便地控制首屏代码的体积,加快加载速度。

抛开具体细节不谈,一个普通 Vue 组件从创建到展现在页面里,主要经历了以下流程:

// 组件 Object
{
 template: '<div>I am async!</div>'
}
// 经过 compileToFunctions 得到对应的 render function 
with(this) {
 return _c('div', [_v("I am async!")])
}
// 在经过 render 得到 Vnode 再 update 成为真实DOM

动态组件&异步组件与之有什么区别呢?

主要区别在于 render 中 createComponent 这一步,举例。

// 组件
Vue.component('example', {
 template: '<div>I am async!</div>'
})

普通组件在 createComponent 时,会依据开发者自定义的 options,利用 Vue.extend 生成对应的构造函数,从而得到对应的 Vnode 。而一个异步组件

// 异步组件
Vue.component('async-example', function (resolve, reject) {
 // 利用 setTimeout 模拟请求
 setTimeout(function () {
  // 向 `resolve` 回调传递组件定义
  resolve({
   template: '<div>I am async!</div>'
  })
 }, 1000)
})

则是要经过一系列处理,具体过程如下

在源码的 create-component。

// async component
let asyncFactory
if (isUndef(Ctor.cid)) {
 asyncFactory = Ctor
 Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context)
 if (Ctor === undefined) {
  // return a placeholder node for async component, which is rendered
  // as a comment node but preserves all the raw information for the node.
  // the information will be used for async server-rendering and hydration.
  return createAsyncPlaceholder(
   asyncFactory,
   data,
   context,
   children,
   tag
  )
 }
}

首先 Ctor 就与之前不同,这里为一个 function

function (resolve, reject) {
 // 利用 setTimeout 模拟请求
 setTimeout(function () {
  // 向 `resolve` 回调传递组件定义
  resolve({
   template: '<div>I am async!</div>'
  })
 }, 1000)
}

之后调用 resolveAsyncComponent(asyncFactory, baseCtor, context)

resolveAsyncComponent 在源码的 resolveAsyncComponent。

resolveAsyncComponent 的主要功能是定义 Ctor 所需要的 resolve 、reject 函数

// factory 为 Ctor
factory(resolve, reject)

以 resolve 函数为例

const resolve = once((res: Object | Class<Component>) => {
 // 缓存 resolved
 factory.resolved = ensureCtor(res, baseCtor)
 // 强制渲染
 if (!sync) {
 	forceRender(true)
 }
})

once 字面理解,就是只调用一次。当 Ctor 中 setTimeout 结束时调用。

ensureCtor 就是 Vue.extend 的封装以适应不同场景,所以 resolve 函数的主要功能就是在异步完成时,将得到的 Ctor 转化为构造函数,缓存在 factory.resolved 中。

之后利用 forceRender(true) 强制重新 render,由于之前缓存了 factory.resolved,resolveAsyncComponent 函数就直接返回了组件的构造函数。

if (isDef(factory.resolved)) {
 return factory.resolved
}

之后就与普通组件一致了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Javascript 跨域访问解决方案
Feb 14 Javascript
尝试在让script的type属性等于text/html
Jan 15 Javascript
带左右箭头图片轮播的JS代码
Dec 18 Javascript
jquery easyui使用心得
Jul 07 Javascript
js实现显示当前状态的导航效果代码
Aug 28 Javascript
全面解析Bootstrap排版使用方法(文字样式)
Nov 30 Javascript
阿里巴巴技术文章分享 Javascript继承机制的实现
Jan 14 Javascript
jquery操作select元素和option的实例代码
Feb 03 Javascript
AngularJS上拉加载问题解决方法
May 23 Javascript
详解node.js搭建代理服务器请求数据
Apr 08 Javascript
JavaScript插入排序算法原理与实现方法示例
Aug 06 Javascript
vue组件创建的三种方式小结
Feb 03 Javascript
微信小程序按钮点击跳转页面详解
May 06 #Javascript
详解vue中移动端自适应方案
May 05 #Javascript
解决ie11 SCRIPT5011:不能执行已释放Script的代码问题
May 05 #Javascript
彻底揭秘keep-alive原理(小结)
May 05 #Javascript
angular4+百分比进度显示插件用法示例
May 05 #Javascript
vuejs数据超出单行显示更多,点击展开剩余数据实例
May 05 #Javascript
Vue+Express实现登录状态权限验证的示例代码
May 05 #Javascript
You might like
剧场版动画《PSYCHO-PASS 3 FIRST INSPECTOR》3月27日日本上映!
2020/03/06 日漫
Dwz与thinkphp整合下的数据导出到Excel实例
2014/12/04 PHP
解决安装WampServer时提示缺少msvcr110.dll文件的问题
2017/07/09 PHP
php创建类并调用的实例方法
2019/09/25 PHP
PHP 8新特性简介
2020/08/18 PHP
TFDN图片播放器 不错自动播放
2006/10/03 Javascript
JavaScript获取页面上某个元素的代码
2011/03/13 Javascript
js 实现 input type=&quot;file&quot; 文件上传示例代码
2013/08/07 Javascript
js获取页面传来参数的方法
2014/09/06 Javascript
JQuery实现的购物车功能(可以减少或者添加商品并自动计算价格)
2015/01/13 Javascript
JavaScript中数据结构与算法(二):队列
2015/06/19 Javascript
JS实现双击屏幕滚动效果代码
2015/10/28 Javascript
JavaScript高阶函数_动力节点Java学院整理
2017/06/28 Javascript
webpack分离css单独打包的方法
2018/06/12 Javascript
JavaScript控制浏览器全屏显示简单示例
2018/07/05 Javascript
JS基于Location实现访问Url、重定向及刷新页面的方法分析
2018/12/03 Javascript
JS中比较两个Object数组是否相等方法实例
2019/11/11 Javascript
js实现课堂随机点名系统
2019/11/21 Javascript
Python 专题六 局部变量、全局变量global、导入模块变量
2017/03/20 Python
Python竟能画这么漂亮的花,帅呆了(代码分享)
2017/11/15 Python
python框架中flask知识点总结
2018/08/17 Python
python实现对服务器脚本敏感信息的加密解密功能
2019/08/13 Python
不到20行实现Python代码即可制作精美证件照
2020/04/24 Python
浅谈CSS3中display属性的Flex布局的方法
2017/08/14 HTML / CSS
菲律宾优惠券网站:MetroDeal
2019/04/12 全球购物
会计学应届毕业生推荐信
2013/11/04 职场文书
护理专业求职信
2014/06/15 职场文书
青年志愿者活动方案
2014/08/17 职场文书
2014年幼儿园国庆主题活动方案
2014/09/16 职场文书
群众路线个人自我剖析材料
2014/10/07 职场文书
小学数学教师研修感悟
2015/11/18 职场文书
一个家长教育孩子的心得体会
2016/01/15 职场文书
导游词之日月潭
2019/11/05 职场文书
销区经理年终述职报告模板
2019/11/28 职场文书
教你使用Jenkins集成Harbor自动发布镜像
2022/04/03 Servers
零基础学java之带返回值的方法的定义和调用
2022/04/10 Java/Android