大家好,我是卡颂。
我是个恋旧的人,Github
头像还是上古期间端游 仙剑奇侠传 的截图。
对于前端,如果能 jQuery
一把梭,我是很开心的。
React
、Vue
的遍及让大家习惯了 虚构 DOM
的存在。然而 虚构 DOM
肯定是最优解么?
举个例子,要进行如下 DOM
挪动操作:
// 变动前
abcd
// 变动后
dabc
用 jQuery
时调用 insertBefore
把d
挪到 a
后面就行。而 React
基于 虚构 DOM
的 Diff
会顺次对 abc
执行appendChild
,将他们顺次挪到最初。
1 次 DOM
操作 vs 3 次 DOM
操作,显然前者更高效。
那么有没有框架能砍掉 虚构 DOM
,间接对 DOM
节点执行操作,实现全自动jQuery
?
有的,这就是最近出的petite-vue
。
浏览完本文,你会从原理层面理解该框架,如果你还有精力,能够在此基础上深刻框架源码。
全自动 jQuery 的实现
能够将原理概括为一句话:
建设
状态
与更新 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
课程。