Vue2的组件化原理刨析

138 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

Vuejs环境

以下是vuejs源码的目录

1654085011(1).jpg

分别有:核心代码之外nodeModules目录、scripts下的构建脚本目录、Src目录下的源码,TS的类型声明文件夹,Flow文件夹是针对TS的类型声明的专享文件。

组件化机制

组件声明方法:

Vue.component() 组件注册使用extend方法,将配置转换为构造函数并且添加到component选项内

创建组件实例并挂载

  • 观察生成的渲染函数
"with(this){return _c('div',{attrs:{"id":"my"}},[
 _c('h1',[_v("虚拟DOM")]),_v(" "),
 _c('p',[_v(_s(foo))]),_v(" "),
 _c('comp')
],1)}"

注意:这个是获取一个Id为:mydiv在内的H1标签和P标签,其中_c('comp')对与组件的处理并无特殊之处。

  • 组件实例创建
  1. 初始化 通过init方法初始化(传参为包括vnode和当前inserted属性值)把当前元素引入到指定的Vvnode.element然后创建元素属性值。
initComponent(vnode, insertedVnodeQueue)
  1. 插入到父元素 创建完成后把当前实例插入到父元素,把当前虚拟Dom、属性、父级元素和Ref的元素
insert(parentElement, vnode.element, refElement)
if (isTrue(isReactivated)) {
 reactivateComponent(vnode, insertedVnode,  parentElement, refElement)
}

整体创建流程

  • 创建根实例 在第一次渲染时,会得到整个的vnode树形,并把该组件创建挂载,然后把Vnode转换成Dom结构
  • 创建组件VNODE 实际执行VNODE创建的函数,但是传入的tag是非保留的标签,因此可以判定为自定义组件通过它去创建的。但是创建组件Vnode,保存了上一步得到的组件构造函数、Props、事件等等
  • 创建组件实例 根组件执行更新函数时,会递归创建子元素和子组件,入口createElm

createEle的路径: core/vdom/patch.js

总结

vue2增加了Vnodepath算法这是非常好的,但同时也存在一定的问题,比如 混入的方式在逻辑服用方面存在命名冲突和来源不明的问题,这是大家值得注意的!!请大家尽情评论