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 相关文章推荐
prototype 学习笔记整理
Jul 17 Javascript
javascript之bind使用介绍
Oct 09 Javascript
String.prototype实现的一些javascript函数介绍
Nov 22 Javascript
extjs 分页使用jsp传递数据示例
Jul 29 Javascript
实例详解angularjs和ajax的结合使用
Oct 22 Javascript
bootstrap学习笔记之初识bootstrap
Jun 21 Javascript
基于Angularjs+mybatis实现二级评论系统(仿简书)
Feb 13 Javascript
微信小程序学习之数据处理详解
Jul 05 Javascript
通过vue-cli3构建一个SSR应用程序的方法
Sep 13 Javascript
node使用Mongoose类库实现简单的增删改查
Nov 08 Javascript
详解node.js 事件循环
Jul 22 Javascript
基于elementUI竖向表格、和并列的案例
Oct 26 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动态创建Web站点的方法
2011/08/14 PHP
PHP实现的mongoDB数据库操作类完整实例
2018/04/10 PHP
jQuery获取(选中)单选,复选框,下拉框中的值
2014/02/21 Javascript
jQuery图片切换插件jquery.cycle.js使用示例
2014/06/16 Javascript
javascript变量声明实例分析
2015/04/25 Javascript
javascript数组去重的六种方法汇总
2015/08/16 Javascript
javascript事件绑定学习要点
2016/03/09 Javascript
JS中的==运算: [''] == false —&gt;true
2016/07/24 Javascript
实现隔行换色效果的两种方式【实用】
2016/11/27 Javascript
Vue.js路由组件vue-router使用方法详解
2016/12/02 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
2016/12/05 Javascript
jQuery中get方法用法分析
2016/12/07 Javascript
easyUI实现类似搜索框关键词自动提示功能示例代码
2016/12/27 Javascript
js实现五星评价功能
2017/03/08 Javascript
利用JS响应式修改vue实现页面的input值
2019/09/02 Javascript
Vue+iview+webpack ie浏览器兼容简单处理
2019/09/20 Javascript
JavaScript 实现同时选取多个时间段的方法
2019/10/17 Javascript
python批量下载图片的三种方法
2013/04/22 Python
对python mayavi三维绘图的实现详解
2019/01/08 Python
使用Python检测文章抄袭及去重算法原理解析
2019/06/14 Python
python查看数据类型的方法
2019/10/12 Python
python3.6中anaconda安装sklearn踩坑实录
2020/07/28 Python
Python爬虫爬取有道实现翻译功能
2020/11/27 Python
泰国办公用品购物网站:OfficeMate
2018/02/04 全球购物
Groupon法国官方网站:特卖和网上购物高达-70%
2019/09/02 全球购物
化工工艺专业求职信
2013/09/22 职场文书
企业给企业的表扬信
2014/01/13 职场文书
升国旗仪式主持词
2014/03/19 职场文书
高中生操行评语
2014/04/25 职场文书
党员查摆剖析材料
2014/10/10 职场文书
党员三严三实对照检查材料
2014/10/13 职场文书
2015年项目工作总结
2015/04/29 职场文书
一个家长教育孩子的心得体会
2016/01/15 职场文书
2016年入党心得体会范文
2016/01/23 职场文书
2019年健身俱乐部的创业计划书
2019/08/26 职场文书
Springboot配置suffix指定mvc视图的后缀方法
2021/07/03 Java/Android