vue组件化原理(vue组件化和模块化区别)
一、组件化机制
组件注册使用extend方法将配置转换为构造函数并添加到components选项
全局声明Vue.component();
局部声明components
组件实例创建及挂载
这是生成组件的渲染函数:
"with(this){return _c('div',{attrs:{"id":"demo"}},[ //_c=createElement _c('h1',[_v("虚拟DOM")]),_v(" "),//名字,组件 _c('p',[_v(_s(foo))]),_v(" "), _c('comp') // 传入自定义组件 ],1)}"复制代码
二、整体流程
new Vue()->$mount()->vm._render()->createElement()->createComponent()->vm._update->patch()->createElm->createComponent();
下面说下每个流程执行的工作内容:
1、创建根实例
首次_render()的时候,会拿到整棵树的VNode结构,其中自定义组件相关的主要是:
createComponent();src/core/vdom/create-component.js 执行组件vnode的创建,会先判断传入的标签类型,然后处理组件的属性(监听器,双向绑定等),然后安装组件的管理钩子和系统默认的钩子。
createComponent();src/core/vdom/patch.js 创建组件实例并进行挂载,vnode转换为真实DOM。
2、创建组件VNode
createElement执行虚拟dom的创建函数,由于是自定义组件,所以tab标签不会保留,直接创建。
createComponent 创建组件VNode,保留上一步得到的组件构造函数,参数props,事件等
3、创建组件实例
createElm根组件执行函数更新时,会递归创建子元素和子组件
首次执行_update时,patch会通过createElm创建根元素,也就是子元素的生成在这里。
createComponent组件实例的创建、挂载生成,插入到父元素的执行
if (isDef(i = i.hook) && isDef(i = i.init)) { i(vnode, false /* hydrating */); } if (isDef(vnode.componentInstance)) { //实例创建完毕,初始化它的属性 initComponent(vnode, insertedVnodeQueue);// 元素引⽤指定vnode.elm,元素属性创建等 insert(parentElm, vnode.elm, refElm);// 插⼊到⽗元素DOM中 if (isTrue(isReactivated)) { reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm) } return true; }复制代码
三、总结
上面说的都是Vue2的组件化原理和流程,相对于vue1来说有更大的改变,在项目应用中有很强的适应性、跨平台和性能是里程碑的版本。
但是也有一些问题的存在:
数据响应式实现在性能上存在问题,对象和数组的处理上不一致引入了额外的API
没有充分利用预编译的优势,patch过程还有不少优化空间
响应式模块、渲染器模块都放在了核心模块中,后期扩展不太方便
选项式的编程模式在复杂业务的时候不利于维护
作者:小鲸鱼mm
链接:https://juejin.cn/post/7029605142525640735