vue内部运行机制

本文详细阐述Vue的内部流程,包括new Vue()初始化、$mount挂载、compile编译、响应式原理与批量异步更新策略、以及patch与diff算法。通过分析数据劫持、依赖收集与发布者-观察者模式,揭示Vue如何实现高效地更新视图。此外,探讨了为什么需要批量更新机制以及使用diff算法的优点。
摘要由CSDN通过智能技术生成

本文主要讲述 vue内部运行机制

 阅读本文可收获
 1.对vue内部运行机制有系统性的了解
 2.数据劫持 + 发布订阅者模式 实现响应式
 3.编译过程简单了解
 4.vue的异步批量更新策略
 5.为什么引入vNode 以及 diff 算法
 6.patch 是如何比较虚拟节点并得出差异的 

内部流程总览图

1.简述内部流程

1.1 new Vue()初始化 与 数据劫持

实例化vue对象new Vue(),会调用_init()函数进行初始化,这个过程会初始化 生命周期、事件、 props、 methods、 data、 computed 与 watch 等。并通过Object.defineProperty进行数据劫持,设置get,set,用于后期的依赖收集以及响应式!

1.2 $mount 挂载

初始化结束,会执行$mount进行挂载,此时会判断是否存在render funtion,如果存在则执行,否则会进入compile编译阶段;

在main.js,会存render funtion 执行render 渲染最终挂载到 #app 这个dom中

v2
new Vue({router,render: (h) => h(App),
}).$mount('#app');

v3
createApp(App).use(store).use(router).mount("#app") 

如果是页面组件或者业务组件会对 template 进行编译,进而得到 render function ,执行render 得到 vNode, 进行 patch 过程最终进行渲染并挂载到对应的文档dom

$mount()本质是想将render渲染模板挂载到文档dom中;

1.3 compile() 编译

编辑阶段会调用compile(),可以分成 parseoptimizegenerate 三个阶段,最终需要得到 render function;

parse 会用正则等方式解析 template 模板中的指令、class、style等数据,形成AST。

我们大概看下AST是什么样的

<div :class="c" class="demo" v-if="isShow"><span v-for="item in sz">{
  {item}}</span>
</div>

{/* 标签属性的map,记录了标签上属性 */'attrsMap': {':class': 'c','class': 'demo','v-if': 'isShow'},/* 解析得到的:class */'classBinding': 'c',/* 标签属性v-if */'if': 'isShow',/* v-if的条件 */'ifConditions': [{'exp': 'isShow'}],/* 标签属性class */'staticClass': 'demo',/* 标签的tag */'tag': 'div',/* 子标签数组 */'children': [{'attrsMap': {'v-for': "item in sz"},/* for循环的参数 */'alias': "item",/* for循环的对象 */'for': 'sz',/* for循环是否已经被处理的标记位 */'forProcessed': true,'tag': 'span','children': [{/* 表达式,_s是一个转字符串的函数 */'expression': '_s(item)','text': '{
  {item}}'}]}]
} 

optimize 的主要作用是标记 static 静态节点(还标记了注释节点,文本节点等) 这是 Vue 在编译过程中的一处优化,后面当 update 更新界面时,会有一个 patch 的过程, diff 算法会直接跳过静态节点,从而减少了比较的过程,优化了 patch 的性能。

generate 是将 AST 转化成 render function 字符串的过程,得到结果是 render 的字符串以及 staticRenderFns 字符串。

在经历过 parseoptimizegenerate 这三个阶段以后,组件中就会存 render function 了。render function 会被转化成 VNode 节点.

VNode 是就是一个json对象,用来描述改节点; 例如

Virtual DOM
{tag: 'div', /*说明这是一个div标签*/children: [ /*存放该标签的子节点*/{tag: 'a', /*说明
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值