如何在不看源码状况下学petite-vue源码

前言

怎么快怎么来,你们的时间都宝贵,用最短的时间学到最多的知识。

咱们能够将petite-vue理解为:用真实DOM取代Vue模版的简易Vuehtml

好比以下Demovue

<script type="module">
  import { createApp } from '../src'
  createApp({count: 0}).mount()
</script>

<div v-scope> <button @click="count++">add 1</button> <p>{{count}}</p> </div>  
复制代码

div及其子孙节点是真实的DOM标签,因此页面初始化时以下:node

接着执行以下代码,完成petite-vue初始化:react

createApp({count: 0}).mount()
复制代码

此时页面:git

读框架源码切忌一上手就从入口函数一路调试,很容易就懵逼了。正确的方式是像剥洋葱同样一层一层剥开:github

这好像是大蒜?

因此,让咱们先从Performance面板看看首屏渲染的调用栈:框架

调用栈大致分为蓝框、红框两部分,先看左边蓝框部分:函数

经过createContextreactive关键词判断大概是建立响应式上下文。至于响应式的含义,咱们还不清楚。post

接着看右边红框部分:url

从调用栈深度、页面渲染的效果咱们猜想,这部分作的工做包括:

  • 遍历DOM

  • 完成数据与视图的双向绑定

  • 初始化渲染

接下来,咱们来验证猜测。

注意,到目前为止,咱们一行源码都还没看

验证遍历DOM

调用栈中walkwalkChildren被调用屡次,大几率他们就是具体遍历工做执行的方法,让咱们确认下。

在源码walk方法中打上log

export const walk = (node: Node, ctx: Context): ChildNode | null | void => {
  console.log('walk', node);
  // ... 
}
复制代码

排除换行符"\n "对应的文本节点,打印顺序以下:

walk div
walk <button>add 1</button>
walk "add 1"
walk <p>0</p>
walk "0"
复制代码

从打印结果看,这是个深度优先遍历(若是有子节点就遍历子节点,没有子节点就遍历兄弟节点)

显然,petite-vue mount时采用深度优先遍历,并对遍历到的每一个与上下文状态相关的DOM节点进行处理。

Demo中,上下文包含状态{count: 0}

createApp({count: 0}).mount()
复制代码

在遍历后<p>{{count}}</p>变为<p>0</p>

肯定双向绑定的粒度

接下来咱们须要确认双向绑定的做用范围,即:

触发更新后,多大范围的DOM会被从新遍历并执行相应DOM操做?

打开Performance后,点击<button>add 1</button>触发更新:

能够看到,没有任何walkwalkChildren(或相似遍历过程),只调用了reactiveEffect一个方法就更新了DOM

这意味着mount时的深度优先遍历创建了状态更新DOM的方法之间一一对应的关系。

由于对应关系肯定了,就再也不须要额外的遍历过程肯定须要变化的DOM

当更新状态后,只须要找到与他有关系的更新DOM的方法执行就行。

好比:将count状态与以下函数创建联系:

function setCount(value) {
  p.textContent = value;
}
复制代码

每当count变化后调用setCount(count)就能更新p对应DOM

因此,petite-vue的工做原理,主要包括两点:

  1. mount时深度优先遍历DOM,对有状态的DOM(好比<p>{{count}}</p>)创建状态更新DOM的方法之间一一对应的关系

  2. update时找到该状态对应的更新DOM的方法并执行

能够看到,即便不深刻源码,也能大致了解工做流程。

若是你想更进一步,好比了解关系是如何创建的(涉及到响应式更新),那么就须要深刻源码了。

这里推荐Vue MasteryVue 3 Reactivity课程,能够补齐响应式更新这块知识。

总结

本文介绍了复杂框架源码的阅读办法 —— 即从抽象到具体。

  1. mount时与update时的调用栈推导出总体工做流程

  2. 总体工做流程中发现核心知识 —— 响应式更新

当掌握总体工做流程响应式更新后,再阅读本身感兴趣的部分才不至于陷入庞大的代码量中。

你,学废了么?

最后,创做不易,若是对你们有所帮助,但愿你们点赞支持,有什么问题也能够在评论区里讨论😄~

若是你以为这篇文章对你有点用的话,麻烦请给咱们的开源项目点点star: http://github.crmeb.net/u/defu 不胜感激 !
来自 “开源世界 ” ,连接:   https://ym.baisou.ltd/post/776.html
相关文章
相关标签/搜索