专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧

研究基于 Vue版本【2.5.17】

今天就要开启我们 Component 探索之旅,旅途有点长,各位请坐好,不要睡着了

内容的主题是,Component 的创建过程,从调用 component,到 component 挂载,到底经历了什么?欢迎来到 component 的内心世界

Component 创建,我主要分了两个流程

1、创建 组件 VNode

2、挂载 组件 DOM

每个流程涉及源码都很多,所以每个流程写一篇文章。没错了,今天讲的就是 创建组件 VNode

场景设置

首先,我们假定现在有这么一个模板,使用了 test 组件

然后页面噼里啪啦执行到了 准备挂载DOM 的步骤(之前的部分跟本主题无关,跳过)

然后页面准备执行渲染函数 render,嗯,就是执行上面模板生成的渲染函数,如下

没有错,我们的 Vue 已经走到了这一步,那么我们的突破口是什么?

没错,就是 _c

function _createElement(

context, tag, data, children

){

var vnode;

var options = context.$options

// 从父组件选项上拿到 对应的组件的选项

var Ctor = options.components[tag]

if (正常的HTML标签) { ....直接新建VNode }

else if ( Ctor ) {

vnode = createComponent(

Ctor, data, context,

children, tag

);

}

return vnode

}

今天讲的是 component,跳过其他,直接走到 第二个 if,嗯,他调用了一个 createComponent

好的,我去前面探探路

function createComponent(

Ctor, data, context,

children, tag

){

var baseCtor = context.$options._base;

// 创建组件构造函数

Ctor = baseCtor.extend(Ctor);

var vnode = new VNode("vue-component-" + (Ctor.cid) + name,

data, undefined, undefined,

undefined, context,

{

Ctor: Ctor}

);

return vnode}

这个 createComponent 什么鬼的,作用大概是

1、创建组件构造函数

2、处理父组件给子组件的数据

3、创建组件 外壳 VNode

由于处理数据什么的,跟本内容无关,所以其他源码一律去掉,那么就只剩下两个流程

下面就开始这两个流程

创建组件构造函数

上面的源码中有两句话(如下),作用就是为组件创建一个构造函数!

var baseCtor = context.$options._base;

Ctor = baseCtor.extend(Ctor);

看得懂吗?看懂了?好吧,那我就不讲了

算了,算了,还是讲吧,毕竟当时自己也是懵逼的

首先,context 是什么?

context 是执行整个渲染函数的上下文对象,很明显,这里就是页面的 实例vm 了

那么,$options 是什么?

$options 就是 实例自定义选项 和 全局选项合并之后的 产物

Vue.prototype._init = function(options){

.....

vm.$options = mergeOptions( // 把两个对象合并

vm.constructor.options,

options, vm

);

.....

}

vm.constructor 是什么?

没错,就是 Vue,你使用 new Vue 创建的页面,构造函数肯定是 Vue 啦

vm.constructor.options 是什么?

看下面

Vue.options = Object.create(null);

Vue.options.components = Object.create(null);

Vue.options.directives = Object.create(null);

Vue.options.filters = Object.create(null);

Vue.options._base = Vue;

Vue 在引入的时候,就完成了很多初始化的内容,这里就是其中给 Vue 增加options 的部分

你看到的 component 啊,filter 什么的啊,没错,保存的就是你全局注册的 component,filter

然后每个页面都能使用到 全局组件,全局filter 的原因

就是因为在 页面实例初始化的时候,把 页面选项 和 全局选项私下合并了

然后,你应该能看到这一句,保存了 Vue 构造函数在 options._base 中

Vue.options._base = Vue;

那么,你应该能理解前面出现的源码了

var baseCtor = context.$options._base;

没错!baseCtor 拿到的就是 Vue!!!!

然后还有一句

Ctor = baseCtor.extend(Ctor);

既然 baseCtor 是 Vue,那 baseCtor.extend 是 Vue.extend?没有错!

正是他!完成了创建组件构造函数的伟大之举!!让我们一起来欣赏下

Vue.extend = function(extendOptions){

// this 指向Vue

var Super = this;

var Sub = function VueComponent(options){

this._init(options);

};

// 原型链继承Sub.prototype = Object.create(Super.prototype);

Sub.prototype.constructor = Sub;

// Super 永远是 Vue,所以这里就是 合并全局选项

// 现在 Super 就是 vue,把 Vue 和 Sub 合并

// 是把一些全局的组件 指令合并到 Sub 中

Sub.options = mergeOptions(

// optios 还包括 mixins 注入的全局

Super.options,

extendOptions

);

return Sub};

这个函数,会返回一个函数 VueComponent,他就是组件的构造函数!用来下篇文章创建组件实例的!!

上面的源码,做的事,简单说,就是继承父类Vue,然后合并 options 等

最后,提一下,所有实例的父类构造函数 Super 都是 Vue

并不是说,组件 a 有一个子组件b,然后组件b 的父类构造函数就是 a.contructor,这是不对的,永远是Vue,谁都是 Vue

创建组件外壳VNode

现在就是前面代码 createComponent 中的最后一步了

注意注意,这里创建的是【组件外壳节点】,内部节点还没有上场,在下篇文章才出现

至于,什么是外壳节点,去看下我的 VNode - 源码版

跳到相关内容看就好了

var vnode = new VNode(

"vue-component-" + Ctor.cid + name,

data, undefined, undefined,

undefined, context,

{

Ctor: Ctor}

);

那么这个外壳节点的作用是什么?

1、保存刚创建好的组件构造函数,下篇文章中会调用到

2、保存父组件给子组件 关联的数据,比如 event,props 之类的(由于跟本主题无关,为了整洁,统统去掉了)

总结

Component 创建 外壳节点的流程,总结如下

1页面渲染函数执行

2_c('test')  执行

3createElement  碰到 tag 是一个组件

4从父组件中,拿到 test 组件的options,传入 createComponent (作用是创建构造函数和 VNode)

5createComponent 调用 Vue.extend 创建组件构造函数

6新建 VNode,并把构造函数和父组件给子组件的数据保存进去

7返回 VNode

最后

鉴于本人能力有限,难免会有疏漏错误的地方,请大家多多包涵,如果有任何描述不当的地方,欢迎后台联系本人,领取红包

长按关注>>>

盘它

vue如何创建vnode_【Vue原理】Component - 源码版 之 创建组件VNode相关推荐

  1. spring系列-注解驱动原理及源码-spring容器创建流程

    目录 一.spring容器的refresh()[创建刷新] 二.BeanFactory 的创建及预准备工作 1.prepareRefresh()刷新前预处理工作. 2.obtainFreshBeanF ...

  2. c++ gdb 绑定源码_【Vue原理】VNode 源码版

    ↑点击上方 "神仙朱" 一起研究Vue源码吧 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版 ...

  3. element 往node里面增加属性值_【Vue原理】Compile - 源码版 之 Parse 属性解析

    写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 [2.5.17] 如果你觉得排版难 ...

  4. 【Vue原理】Diff - 源码版 之 Diff 流程

    写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 [2.5.17] 如果你觉得排版难 ...

  5. vue使用computed有参数_【Vue原理】Computed - 源码版

    专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本2.5.17 今天要记录 computed 的源码,有时候想,理 ...

  6. 初始化触发点击事件_【Vue原理】Event - 源码版 之 自定义事件

    专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本[2.5.17] Vue 的自定义事件很简单,就是使用 观察者模 ...

  7. 【Vue原理】Methods - 源码版

    写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 [2.5.17] 如果你觉得排版难 ...

  8. Vue parse之 从template到astElement 源码详解

    前奏 在紧张的一个星期的整理,笔者的前端小组每个人都整理了一篇文章,笔者整理了Vue编译模版到虚拟树的思想这一篇幅.建议读者看到这篇之前,先点击这里预习一下整个流程的思想和思路. 本文介绍的是Vue编 ...

  9. 利用SpringBoot和Vue实现前后端分离(附源码)

    利用SpringBoot和Vue实现前后端分离(附源码) 引言: 本文主要分享了SpringBoot和Vue整合实现前后端分离,实现了简单的增删查改:包括:项目的搭建.后端的实现.前台的实现:(附源码 ...

最新文章

  1. MyBatis千万级数据查询解决方案,避免OOM
  2. ZooKeeper的事务日志和快照
  3. Django websocket 长连接使用
  4. eclipse注释模板_Intellij IDEA设置默认文档注释
  5. epoll的内核实现
  6. 【原创】不用封装jar包 直接引入工程使用的方法(类似android的 is Library功能)...
  7. 论文解读丨文档结构分析
  8. Java虚拟机专题之垃圾回收(读书笔记)
  9. 判断用户用手机访问还是用电脑访问网页
  10. win10如何下载python3_Win10环境中如何实现python2和python3并存
  11. 20155324 《信息安全系统设计基础》课程总结
  12. linux关闭邮件提示错误,LINUX命令关闭 You have mail in /var/spool/mail/root邮件提醒功能...
  13. 国内首家!携程周三、周五可在家“躺平”:76%员工主动报名 !网友:我酸了...
  14. CVE-2019-0708高危漏洞,各家安全厂商的扫描修复方案
  15. 蓝桥杯 试题 基础练习 圆的面积
  16. Python学习之学校教学(辨别身份证的真伪,并判断性别)
  17. java计算机毕业设计基于微信小程序的校园外卖订餐系统APP
  18. 大唐芙蓉园-莫安迪摄影作品
  19. MySQL中主键和unique的区别
  20. java位运算符(、|、~、^、、 )

热门文章

  1. php如何获取图片地址,js如何直接获取网页中图片地址
  2. 前端笔试面试知识点总结(随缘复习,慢更)
  3. 低版本3dmax怎么打开高版本文件?3种简单的方法拿走不谢
  4. 电脑游戏业编年史之八──幻影的年代
  5. 利用CurrentCulture将人民币符号更改为欧元符号
  6. 用c语言编写因子分析程序,相应分析的R包ca和mca,cca,RDA的R实现整理
  7. 微信小程序页面跳转限制问题
  8. 视频播放器制作学习之旅----迷途羔羊(DirectDraw DirectShow)
  9. 初三学生多会筹备计算机中考考试,初三一模考试是什么时候 初三一模如何复习...
  10. snap has no updates available