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 相关文章推荐
jQuery源码分析之Event事件分析
Jun 07 Javascript
关于jQuery对象数据缓存Cache原理以及jQuery.data详解
Apr 07 Javascript
Javascript单元测试框架QUnitjs详细介绍
May 08 Javascript
JavaScript中变量声明有var和没var的区别示例介绍
Sep 15 Javascript
js简单实现点击左右运动的方法
Apr 10 Javascript
javascript实现简易计算器的代码
May 31 Javascript
AngularJS入门教程之静态模板详解
Aug 18 Javascript
Vue异步组件使用详解
Apr 08 Javascript
Angular2搜索和重置按钮过场动画
May 24 Javascript
JavaScript实现的简单Tab点击切换功能示例
Jul 06 Javascript
Vue组件中的data必须是一个function的原因浅析
Sep 03 Javascript
浅谈在vue-cli3项目中解决动态引入图片img404的问题
Aug 04 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
Discuz Uchome ajaxpost小技巧
2011/01/04 PHP
解析CodeIgniter自定义配置文件
2013/06/18 PHP
php使用CURL模拟GET与POST向微信接口提交及获取数据的方法
2016/09/23 PHP
php实现给二维数组中所有一维数组添加值的方法
2017/02/04 PHP
PHP魔术方法之__call与__callStatic使用方法
2017/07/23 PHP
phpMyAdmin通过密码漏洞留后门文件
2018/11/20 PHP
通过代码实例解析PHP session工作原理
2020/12/11 PHP
jQuery 打造动态渐变按钮 详细图文教程
2010/04/25 Javascript
Jquery实现图片左右自动滚动示例
2013/09/25 Javascript
jQuery 回车事件enter使用示例
2014/02/18 Javascript
再分享70+免费的jquery 图片滑块效果插件和教程
2014/12/15 Javascript
JavaScript简单实现弹出拖拽窗口(一)
2016/06/17 Javascript
原生js轮播特效
2017/05/18 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
微信小程序实现Session功能及无法获取session问题的解决方法
2019/05/07 Javascript
微信小程序实现蓝牙打印
2019/09/23 Javascript
微信小程序保存图片到相册权限设置
2020/04/09 Javascript
python模拟新浪微博登陆功能(新浪微博爬虫)
2013/12/24 Python
Python选课系统开发程序
2016/09/02 Python
mac安装scrapy并创建项目的实例讲解
2018/06/13 Python
Tornado Web Server框架编写简易Python服务器
2018/07/28 Python
python 获取页面表格数据存放到csv中的方法
2018/12/26 Python
Python浮点型(float)运算结果不正确的解决方案
2020/09/22 Python
一款纯css3实现的颜色渐变按钮的代码教程
2014/11/12 HTML / CSS
联想瑞士官方网站:Lenovo Switzerland
2017/11/19 全球购物
澳大利亚当地最大的时装生产商:Cue
2018/08/06 全球购物
教师岗位职责
2013/11/17 职场文书
个人考核材料
2014/05/15 职场文书
员工合理化建议书
2014/05/19 职场文书
党员干部廉洁承诺书
2014/05/28 职场文书
物流管理专业求职信
2014/05/29 职场文书
单位授权委托书范本
2014/09/26 职场文书
搞笑老公保证书
2015/02/26 职场文书
严以用权专题学习研讨会发言材料
2015/11/09 职场文书
2016校本研修培训心得体会
2016/01/08 职场文书
使用nginx动态转换图片大小生成缩略图
2021/03/31 Servers