最近,我研究了Facebook的React框架。它使用了一个叫做“虚拟DOM”的概念,我并不真正理解这个概念。

什么是虚拟DOM?它的优点是什么?


当前回答

让我们举个例子——虽然是一个很天真的例子:如果你家里的房间里有什么乱七八糟的东西,你需要清理它,你的第一步会是什么?你是要打扫你乱糟糟的房间,还是要打扫整个房子?答案肯定是,你只打扫需要打扫的房间。这就是虚拟DOM的作用。

普通JS遍历或呈现整个DOM,而不是只呈现需要更改的部分。

所以当你有任何变化时,比如你想要添加另一个<div>到你的DOM,那么虚拟DOM将被创建,它实际上不会对实际DOM做任何改变。现在使用这个虚拟DOM,您将检查它与当前DOM之间的区别。并且只有不同的部分(在本例中是新的<div>)将被添加,而不是重新渲染整个DOM。

其他回答

虚拟DOM(VDOM)并不是一个新概念:https://github.com/Matt-Esch/virtual-dom。

VDOM在战略上更新DOM,而不需要重新绘制单个页面应用程序中的所有节点。在树结构中找到一个节点很容易,但SPA应用程序的DOM树可能非常大。在事件发生时查找和更新一个/多个节点并不省时。

VDOM通过创建实际dom的高级抽象来解决这个问题。VDOM是实际DOM的高级轻量级内存树表示。

例如,考虑在DOM中添加一个节点;在内存中保留一个VDOM副本

创建带有新状态的VDOM 将它与使用差分的旧VDOM进行比较。 只更新真实DOM中的不同节点。 将新的VDOM分配为旧的VDOM。

React创建了一个自定义对象树,表示DOM的一部分。例如,它不是创建一个包含UL元素的实际DIV元素,而是创建一个React。包含React的div对象。ul对象。它可以非常快速地操作这些对象,而无需实际接触真正的DOM或通过DOM API。然后,当它呈现一个组件时,它使用这个虚拟DOM来确定它需要对真实DOM做什么,以使两棵树匹配。

您可以将虚拟DOM看作是一个蓝图。它包含了构建DOM所需的所有细节,但由于它不需要真正DOM中所有的重量级部分,因此可以更容易地创建和更改它。

这是对ReactJS中经常提到的Virtual DOM的简要描述和重申。

The DOM (Document Object Model) is an abstraction of structured text, which means it is made of HTML code and css. These HTML elements become nodes in the DOM. There are limitations to the previous methods of manipulating the DOM. Virtual DOM is an abstraction of the literal HTML DOM created well before React was created or used, but for our purposes we will use it in concert with ReactJS. The Virtual DOM is lightweight and detached from the DOM implementation in the browser. The Virtual DOM is essentially a screenshot (or copy) of the DOM at a given time. A way to look at it from a developers perspective is the DOM is the production environment and the Virtual DOM is the local (dev) environment. Each time the data changes in a React app a new Virtual DOM representation of the user interface is created.

为了在ReactJS中创建静态组件,最基本的方法是:

必须从呈现方法返回代码。 您必须将每个类转换为className,因为class是JavaScript中的保留字。 除了更大的变化之外,两个DOM之间还有一些小差异,包括虚拟DOM中出现而HTML DOM中没有出现的三个属性(key、ref和dangerlysetinnerhtml)。

在使用Virtual DOM时,需要理解的一件重要事情是ReactElement和ReactComponent之间的区别。

ReactElement

ReactElement是DOM元素的轻量级、无状态、不可变的虚拟表示。 ReactElement -这是React中的主要类型,位于Virtual DOM中。 ReactElements可以被渲染成HTML DOM var root = React.createElement('div'); ReactDOM。呈现(根,. getelementbyid(例子)); JSX将HTML标记编译为ReactElements Var root = <div/>; ReactDOM。呈现(根,. getelementbyid(例子));

ReactComponent

ReactComponent——ReactComponent是有状态的组件。 反应。createClass被认为是一个ReactComponent。 每当状态改变时,组件都会被重新呈现。

每当ReactComponent发生状态变化时,我们希望对HTML DOM的更改尽可能少,这样ReactComponent就可以转换为ReactElement,然后ReactElement可以插入到Virtual DOM中,快速方便地进行比较和更新。

当React知道diff时,它会被转换为低级代码(HTML DOM),并在DOM中执行。

让我们举个例子——虽然是一个很天真的例子:如果你家里的房间里有什么乱七八糟的东西,你需要清理它,你的第一步会是什么?你是要打扫你乱糟糟的房间,还是要打扫整个房子?答案肯定是,你只打扫需要打扫的房间。这就是虚拟DOM的作用。

普通JS遍历或呈现整个DOM,而不是只呈现需要更改的部分。

所以当你有任何变化时,比如你想要添加另一个<div>到你的DOM,那么虚拟DOM将被创建,它实际上不会对实际DOM做任何改变。现在使用这个虚拟DOM,您将检查它与当前DOM之间的区别。并且只有不同的部分(在本例中是新的<div>)将被添加,而不是重新渲染整个DOM。

所有的答案都很棒。我只是想到了一个比喻,也许可以给一个现实世界的比喻。

真正的DOM就像你的房间,节点是你房间里的家具。虚拟DOM就像我们绘制当前房间的蓝图。

我们都有搬家具的经历,这很累(与在电脑中更新视图相同)。因此,每当我们想要改变位置/添加家具(节点)时,我们只想做非常必要的改变。

蓝图来拯救实现它。我们画了一个新的蓝图,并将其与原蓝图的差异进行比较。这让我们知道哪些部分被改变了,哪些部分保持不变。然后我们对真实的房间进行必要的更改(更新真实DOM上更改的节点)。华友世纪。

(有些人可能会想,为什么我们必须依赖虚拟的DOM,而不直接比较真实的DOM呢?在类比中,比较真实的DOM意味着您必须创建另一个真实的房间,并将其与原始的房间进行比较。只是太贵了。)