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 进行输入框自动匹配字符的小例子
Jun 29 Javascript
jquery.cookie用法详细解析
Dec 18 Javascript
jQuery事件之键盘事件(ctrl+Enter回车键提交表单等)
May 11 Javascript
我的Node.js学习之路(二)NPM模块管理
Jul 06 Javascript
javascript每日必学之继承
Feb 23 Javascript
jquery插件autocomplete用法示例
Jul 01 Javascript
Jquery实现跨域异步上传文件总结
Feb 03 Javascript
超全面的vue.js使用总结
Feb 12 Javascript
js实现百度登录框鼠标拖拽效果
Mar 07 Javascript
js+html5实现侧滑页面效果
Jul 15 Javascript
Vue el-autocomplete远程搜索下拉框并实现自动填充功能(推荐)
Oct 25 Javascript
《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析
Apr 08 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实现小型站点广告管理
2006/10/09 PHP
PHP获取php,mysql,apche的版本信息示例代码
2014/01/16 PHP
手把手编写PHP框架 深入了解MVC运行流程
2016/09/19 PHP
cookie在javascript中的使用技巧以及隐私在服务器端的设置
2012/12/03 Javascript
JS中的this变量的使用介绍
2013/10/21 Javascript
Javascript 鼠标移动上去 滑块跟随效果代码分享
2013/11/23 Javascript
JS小功能(checkbox实现全选和全取消)实例代码
2013/11/28 Javascript
javascript 3d 逐侦产品展示(核心精简)
2014/03/26 Javascript
判断及设置浏览器全屏模式
2014/04/20 Javascript
node.js中的path.dirname方法使用说明
2014/12/09 Javascript
jQuery+css3实现Ajax点击后动态删除功能的方法
2015/08/10 Javascript
js编写三级联动简单案例
2016/12/21 Javascript
在vue项目中使用element-ui的Upload上传组件的示例
2018/02/08 Javascript
JavaScript 跨域之POST实现方法
2018/05/07 Javascript
详解vue-cli中模拟数据的两种方法
2018/07/03 Javascript
Vue实现验证码功能
2019/12/03 Javascript
jQuery表单校验插件validator使用方法详解
2020/02/18 jQuery
pytorch 数据集图片显示方法
2018/07/26 Python
用python 实现在不确定行数情况下多行输入方法
2019/01/28 Python
Python3.5装饰器典型案例分析
2019/04/30 Python
Python弹出输入框并获取输入值的实例
2019/06/18 Python
python字典嵌套字典的情况下找到某个key的value详解
2019/07/10 Python
django 实现celery动态设置周期任务执行时间
2019/11/19 Python
Python3 用什么IDE开发工具比较好
2020/11/28 Python
来自圣地亚哥的实惠太阳镜:Knockaround
2018/08/27 全球购物
adidas瑞典官方网站:购买阿迪达斯鞋子和运动服
2019/12/11 全球购物
读书伴我成长演讲稿
2014/05/07 职场文书
化工实习心得体会
2014/09/09 职场文书
房屋分割离婚协议书范本
2014/12/01 职场文书
计划生育目标责任书
2015/05/09 职场文书
二审答辩状范文
2015/05/22 职场文书
电影开国大典观后感
2015/06/04 职场文书
初中政治教学工作总结
2015/08/13 职场文书
2016年小学端午节活动总结
2016/04/01 职场文书
php中配置文件保存修改操作 如config.php文件的读取修改等操作
2021/05/12 PHP
Python中Matplotlib的点、线形状、颜色以及绘制散点图
2022/04/07 Python