为啥 Vue.js 使用 VDOM?

Posted

技术标签:

【中文标题】为啥 Vue.js 使用 VDOM?【英文标题】:Why is Vue.js using a VDOM?为什么 Vue.js 使用 VDOM? 【发布时间】:2017-10-29 12:08:37 【问题描述】:

According to Vue.js' documentation,它在后台使用 VDOM 来呈现 UI。据我了解,VDOM 主要是为了避免“跟踪依赖”而发明的。使用 VDOM,可以在不知道究竟发生了什么变化的情况下协调应用程序的更大部分。因此,可以使用普通对象和数组来描述视图,并且只需要通知框架有关更改(如 React 中的setState)。然后,比较两个 VDOM 树,并将所需更改的最小集合应用于真实 DOM。

另一方面,Vue.js 使用跟踪依赖项。它确切地知道发生了什么变化,因此可以使用 DOM 绑定。此外,由于大多数 Vue.js 用户已经在使用模板语言,它并没有真正受益于 VDOM 提供的更大灵活性。那么为什么 Evan 决定使用 VDOM?

【问题讨论】:

我猜 vdom 将有助于服务器端渲染。你可以在这里阅读更多信息(vuejs.org/2016/04/27/announcing-2.0) 模板语言可以在不使用 VDOM 抽象的情况下进行服务器渲染。您只需要将模板编译为返回字符串(或字符串流)的函数。 【参考方案1】:

这个设计决策有几个方面。

    可维护性和灵活性。直接 DOM 绑定(如在 Vue 1.x 中)对于单个绑定确实是高效且直接的,但在涉及列表时就不那么重要了。当涉及组合时(例如插槽机制),它会变得更加复杂。对于每一种这样的特性(涉及片段的组合),都需要编写专用的有状态代码,它们可能会相互影响,使系统更难维护。使用 VDOM 将最终的 DOM 操作与功能层清晰地分开 - 功能代码现在通过声明式组合 VNode 来工作,从而更容易维护和添加新功能。

    此外,VDOM 的这种灵活性也可以通过允许用户绕过模板并直接编写渲染函数来向用户展示。

    VDOM 差异不是免费的 - 事实上,当您在大型组件树的根部使用setState() 时,它可能会非常昂贵。这就是为什么在 React 中你需要使用PureComponent 或实现shouldComponentUpdate 来绕过部分组件树。使用 dep 跟踪系统,我们可以自动更准确地检测需要更新的组件,因此即使是 VDOM 也可以从 dep 跟踪系统中受益。

    依赖项跟踪也有其成本 - 对于每个绑定,它需要为跟踪的依赖项分配内存。超细粒度的绑定意味着应用程序中将有数千个反应式观察者,从而导致额外的内存使用。跟踪系统的粒度应该取决于我们正在构建的应用程序类型。基于对典型应用程序结构的观察,Vue 2 通过跟踪每个组件的依赖关系来使用某种“中等粒度”的策略,从而使每个组件成为一个响应式更新边界。

所以 - 将两者结合起来,我们可以从双方获得好处:)

【讨论】:

太棒了!感谢您回答这个问题。我已经看过你在 Nordic.js (youtube.com/watch?v=Ag-1wmHWwS4) 上关于这个主题的精彩演讲,已经涵盖了一些方面。

以上是关于为啥 Vue.js 使用 VDOM?的主要内容,如果未能解决你的问题,请参考以下文章

vue.js 源代码学习笔记 ----- core lifecycle

为啥在 Vue.js 或 React 中使用组件? [关闭]

vue.js 源代码学习笔记 ----- keep-alives

为啥 Laravel 中间件 CORS 不能与 Vue.js 一起使用

为啥要在 vue.js 中计算属性?

vue.js是啥?为啥要在nodejs中安装