你们好,我是卡颂。html
我是个恋旧的人,Github
头像仍是上古时期端游仙剑奇侠传的截图。前端
对于前端,若是能jQuery
一把梭,我是很开心的。vue
React
、Vue
的普及让你们习惯了虚拟DOM
的存在。可是虚拟DOM
必定是最优解么?react
举个例子,要进行以下DOM
移动操做:markdown
// 变化前
abcd
// 变化后
dabc
复制代码
用jQuery
时调用insertBefore
把d
挪到a
前面就行。而React
基于虚拟DOM
的Diff
会依次对abc
执行appendChild
,将他们依次挪到最后。app
1次DOM
操做 vs 3次DOM
操做,显然前者更高效。框架
那么有没有框架能砍掉虚拟DOM
,直接对DOM
节点执行操做,实现全自动jQuery
?学习
有的,这就是最近出的petite-vue
。spa
阅读完本文,你会从原理层面了解该框架,若是你还有精力,能够在此基础上深刻框架源码。3d
能够将原理归纳为一句话:
创建
状态
与更新DOM的方法
之间的联系
好比,对于以下DOM
:
<p v-show="showName">我是卡颂</p>
复制代码
指望showName
状态的变化能影响p
的显隐(经过改变diaplay
)。
实际是创建showName的变化与调用以下方法的联系:
() => {
el.style.display = get() ? initialDisplay : 'none'
}
复制代码
其中el
表明p
,get()
获取showName
当前值。
再好比,对于以下DOM
:
<p v-text="name"></p>
复制代码
name
改变后p
的textContent
会变为对应值。
实际是创建name的变化与调用以下方法的联系:
() => {
el.textContent = toDisplayString(get())
}
复制代码
因此,整个框架的工做原理呼之欲出:初始化时遍历全部DOM
,根据各类v-xx
属性创建DOM
与操做DOM的方法之间的联系。
当改变状态后,会自动调用与其有关的操做DOM的方法,简直就是全自动jQuery
。
因此,框架的核心在于:如何创建联系?
这部分源码都收敛在@vue/reactivity
库中。我并不想带你精读源码,由于这样很没意思,看了还容易忘。
接下来我会经过一个故事为你展现其工做原理,当你了解原理后若是感兴趣能够本身去看源码。
咱们的目标是描述:状态变化与更新DOM的方法之间的联系。说得再宽泛点,是创建状态
与反作用
之间的联系。
即:状态变化 -> 执行反作用
对于一段关系,能够从当事双方的角度描述,好比:
男生指着女生说:这是我女友。
接着女生指着男生说:这是我男友。
你做为旁观者,经过双方的描述就知道他们处于一段恋爱关系。
推广到状态
与反作用
,则是:
反作用
指着状态
说:我依赖这个状态
,他变了我就会执行。
状态
指着反作用
说:我订阅了这个反作用
,当我变了后我会通知他。
能够看到,发布订阅实际上是对一段关系站在双方视角的阐述
举个例子,以下DOM
结构:
<div v-scope="{num: 0}">
<button @click="num++">add 1</button>
<p v-show="num%2">
<span v-text="num"></span>
</p>
</div>
复制代码
通过petite-vue
遍历后的关系图:
框架的交互流程为:
触发点击事件,状态num
变化
通知其订阅的反作用
(effect1
与effect2
),执行对应DOM
操做
若是从情侣关系角度解读,就是:
num
指着effect1
说:这是我女友。
effect1
指着num
说:这是我男友。
num
指着effect2
说:这是我女友。
effect2
指着num
说:这是我男友。
今天咱们学习了一个框架petite-vue
,他的底层实现由多段混乱的男女关系组成,上层是一个个直接操做DOM
的方法。
不知道看完后你有没有兴趣深刻了解下这种关系呢?
感兴趣的话能够看看Vue Mastery
的Vue 3 Reactivity
课程。