中国人中庸之道,中国人造的框架呢?

你们好,我是卡颂。前端

都说中国人讲究中庸之道,中国人造的框架讲究么?数组

本文会从原理层面讲解Vue是如何在运行时与编译时之间保持中庸的平衡。前端框架

UI = fn(state)

几乎全部前端框架工做原理都能用以下公式归纳:markdown

UI = fn(state)
复制代码

UI(视图)能够经过state(状态)通过fn(框架)计算得出。框架

然而具体原理上,框架之间却千差万别。spa

能够按照更新粒度将他们分为三类:3d

  • 树级更新code

  • 组件级更新orm

  • 节点级更新xml

更新粒度没有优劣之分,只是对应不一样的实现

接下来咱们简单了解下不一样粒度更新方式的实现原理。

假设有以下组件树,其中Cpn是一个自定义组件,内部结构为ul>li*2

咱们但愿将Cpn内的一个li更新为黄色:

树级更新

树级更新的框架会再生成一棵完整虚拟DOM树,生成过程当中与以前的虚拟DOM树对应节点进行比较:

找到变化的节点后,执行对应DOM操做。

树级更新框架的特色是:

  • 依赖虚拟DOM

  • 不关心触发更新的节点(由于会经过虚拟DOM的全树对比找到他)

采用这种更新方式最有名的框架就是React

组件级更新

上面的例子,若是是组件级更新框架。

会找到触发更新节点所在组件,生成该组件的虚拟DOM树(而不是全树的虚拟DOM树),生成过程当中与该组件以前的虚拟DOM树对应节点进行比较:

找到变化的节点后,执行对应DOM操做。

组件级更新框架的特色是:

  • 依赖虚拟DOM

  • 关心触发更新的节点(虚拟DOM的对比会做用于该节点所在组件)

采用这种更新方式最有名的框架就是Vue

节点级更新

若是是节点级更新框架,在编译时会根据状态变化对应的DOM变化直接生成对应方法,当状态改变后直接调用对应方法。

上面的例子,在编译时会关联color状态与changeColor方法:

function changeColor(newColor) {
  li.style.color = newColor;
}
复制代码

当改变color状态后直接调用changeColor方法更新li对应DOM

节点级更新框架的特色是:

  • 不依赖虚拟DOM,依赖预编译(创建状态与改变DOM的方法之间的联系)

  • 关心触发更新的节点(节点状态与更新方法一一对应)

采用这种更新方式最有名的框架就是Svelte

中庸的Vue3

Vue做为组件级更新表明,更新粒度介于树级节点级之间。那究竟是中间偏左呢,仍是中间偏右呢?

Vue3说:

我要反复横跳,两边我都要

Vue3中包含三种树状结构:

描述视图的树 -> 虚拟DOM树 -> 真实DOM树
复制代码

其中描述视图的树官方推荐使用模版语法,但也能使用JSX

无论是哪一种方式,最终都会转化为虚拟DOM树

当使用JSX时,Vue3拥有了React运行时的灵活性,此时的Vue3能够看做是增强版React + Mobx

当使用模版语法Vue3引入了预编译技术。此时能够将Vue3的工做流程细化为四步:

描述视图的树 -> VNode树 -> Block数组 -> 真实DOM树
复制代码

其中VNode树就是常规意义的虚拟DOM树Block数组则为VNode树中对状态有依赖,会变化的那部分VNode组成的数组。

好比,对于以下模版语法:

<template>
  <section> <div>i am</div> <p>{{name}}</p> </section>
</template>
复制代码

sectiondiv不包含状态,不会变化,因此会转化为VNode,可是没有对应Block

p包含状态name,会转化为VNodeBlock

当该template所在组件触发name状态变化,以前须要依次建立sectiondivpVNode并进行比较。

有了预编译技术后只须要遍历Block数组进行比较。

用上文的例子即只须要对比一个li节点:

在这种状况下,虽然是使用虚拟DOM组件级更新框架,可是已经很接近节点级更新框架了。

总结

本文按更新粒度介绍了三种不一样类型的框架,以及Vue3在选择JSX模版语法时在灵活性与更新粒度间的灵活变化。

能够说是很符合中庸之道了。

有人会问,使用Vue3的用户大部分都能接受模版语法,为何不直接抛弃虚拟DOM,使用预编译技术,实现真正的节点级更新

一方面,虚拟DOM使框架脱离具体的视图层,更方便跨端渲染。

另外一方面,Vue2社区生态积累了大量基于虚拟DOM的库。

若是是你,在这种状况下会做何选择呢?

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息