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 相关文章推荐
js操作Xml(向服务器发送Xml,处理服务器返回的Xml)(IE下有效)
Jan 30 Javascript
JavaScript 异步调用框架 (Part 3 - 代码实现)
Aug 04 Javascript
解决jquery .ajax 在IE下卡死问题的解决方法
Oct 26 Javascript
jQuery.prototype.init选择器构造函数源码思路分析
Feb 05 Javascript
对frameset、frame、iframe的js操作示例代码
Aug 16 Javascript
基于jQuery的判断iPad、iPhone、Android是横屏还是竖屏的代码
May 11 Javascript
原生javascript实现分享到朋友圈功能 支持ios和android
May 11 Javascript
Bootstrap 网格系统布局详解
Mar 19 Javascript
webpack构建换肤功能的思路详解
Nov 27 Javascript
在Vue中使用highCharts绘制3d饼图的方法
Feb 08 Javascript
vue-router 手势滑动触发返回功能
Sep 30 Javascript
Vue3不支持Filters过滤器的问题
Sep 24 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
PHP中的array数组类型分析说明
2010/07/27 PHP
php实现telnet功能示例
2014/04/08 PHP
smarty模板判断数组为空的方法
2015/06/10 PHP
php中smarty变量修饰用法实例分析
2015/06/11 PHP
PHP实现通过get方式识别用户发送邮件的方法
2015/07/16 PHP
yii2.0整合阿里云oss的示例代码
2017/09/19 PHP
img的onload的另类用法
2008/01/10 Javascript
百度留言本js 大家可以参考下
2009/10/13 Javascript
js中关于String对象的replace使用详解
2011/05/24 Javascript
潜说js对象和数组
2011/05/25 Javascript
Bootstrap4一次重大更新 几乎涉及每行代码
2016/05/16 Javascript
javascript 显示全局变量与隐式全局变量的区别
2017/02/09 Javascript
JS实现仿UC浏览器前进后退效果的实例代码
2017/07/17 Javascript
Node.js静态服务器的实现方法
2018/02/28 Javascript
一个Vue视频媒体多段裁剪组件的实现示例
2018/08/09 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
javascript实现留言板功能
2020/02/08 Javascript
基于JavaScript实现随机点名器
2021/02/25 Javascript
[55:25]VGJ.T vs Optic Supermajor小组赛D组 BO3 第三场 6.3
2018/06/04 DOTA
Python设计模式编程中解释器模式的简单程序示例分享
2016/03/02 Python
Python机器学习之决策树算法
2017/12/22 Python
python中的turtle库函数简单使用教程
2018/07/23 Python
python 文件查找及内容匹配方法
2018/10/25 Python
Django values()和value_list()的使用
2020/03/31 Python
Python 读取位于包中的数据文件
2020/08/07 Python
Hotter Shoes美国官网:英国最受欢迎的舒适鞋
2018/08/02 全球购物
海量信息软件测试笔试题
2015/08/08 面试题
党员学习十八大感想
2014/01/17 职场文书
服装设计专业自荐信
2014/06/17 职场文书
个人买房协议书范本
2014/10/06 职场文书
领导班子整改措施
2014/10/24 职场文书
公安个人四风问题对照检查及整改措施
2014/10/28 职场文书
焦裕禄纪念馆观后感
2015/06/09 职场文书
php字符串倒叙
2021/04/01 PHP
分析JVM源码之Thread.interrupt系统级别线程打断
2021/06/29 Java/Android
mysql 8.0.27 绿色解压版安装教程及配置方法
2022/04/20 MySQL