与其他框架比较
Angular
虽然可能不适用于所有人,但使用 Vue 而不是 Angular 有几个原因。
Vue.js 比 Angular 简单得多,无论是在 API 还是设计方面。你可以快速学习它的大部分内容并提高生产力。
Vue.js 是一种更灵活、更少意见的解决方案。这使你能够以你想要的方式构建应用程序,而不是被迫以 Angular 的方式做所有事情。它只是一个界面层,因此你可以将其用作页面中的轻量级功能,而不是完整的 SPA。它为你提供了更大的空间来混合和匹配其他库,但你也需要做出更多架构决策。例如,Vue.js 的核心默认情况下不包含路由或 ajax 功能,通常假设你使用外部模块捆绑器构建应用程序。这可能是最重要的区别。
Angular 在作用域之间使用双向绑定。虽然 Vue 也支持显式双向绑定,但它默认情况下在组件之间使用单向、从父到子的数据流。使用单向绑定使大型应用程序中数据的流动更容易理解。
Vue.js 在指令和组件之间有更清晰的区分。指令旨在仅封装 DOM 操作,而组件代表一个自包含的单元,它具有自己的视图和数据逻辑。在 Angular 中,两者之间存在很多混淆。
Vue.js 具有更好的性能,并且优化起来容易得多,因为它不使用脏检查。当存在大量观察者时,Angular 会变慢,因为每次作用域中的任何内容发生变化时,都需要重新评估所有这些观察者。此外,如果某个观察者触发了另一个更新,则摘要周期可能需要运行多次才能“稳定”。Angular 用户经常不得不求助于深奥的技术来绕过摘要周期,在某些情况下,根本无法优化具有大量观察者的作用域。Vue.js 根本不会遇到这个问题,因为它使用透明的依赖项跟踪观察系统,并带有异步队列 - 所有更改都会独立触发,除非它们具有显式依赖项关系。你唯一需要的优化提示是
v-for
列表上的track-by
参数。
有趣的是,Angular 2 和 Vue 在解决这些 Angular 1 问题方面存在一些相似之处。
React
React 和 Vue.js 确实有一个共同点,即它们都提供响应式和可组合的视图组件。当然,它们之间也存在很多差异。
首先,内部实现从根本上不同。React 的渲染利用了虚拟 DOM - 实际 DOM 应该是什么样子的内存中表示。当状态发生变化时,React 会对虚拟 DOM 进行完全重新渲染,对其进行差异比较,然后修补实际 DOM。
虚拟 DOM 方法提供了一种在任何时间点描述视图的功能方式,这非常好。因为它不使用可观察对象,并且在每次更新时都重新渲染整个应用程序,因此视图在定义上保证与数据同步。它还为同构 JavaScript 应用程序打开了可能性。
Vue.js 没有使用虚拟 DOM,而是使用实际 DOM 作为模板,并保留对实际节点的引用以进行数据绑定。这将 Vue.js 限制在存在 DOM 的环境中。然而,与普遍的误解相反,虚拟 DOM 并没有使 React 比其他任何东西都快,实际上,Vue.js 在热更新方面比 React 性能更出色,并且几乎不需要手动调整优化。使用 React,你需要在所有地方实现 shouldComponentUpdate
并使用不可变数据结构来实现完全优化的重新渲染。
从 API 角度来看,React(或 JSX)的一个问题是,渲染函数通常涉及很多逻辑,最终看起来更像一段程序(实际上它就是),而不是界面的视觉表示。对于某些开发人员来说,这是一个优势,但对于像我这样的设计师/开发人员混合体来说,拥有一个模板使得更容易直观地思考设计和 CSS。JSX 与 JavaScript 逻辑混合在一起打破了我需要将代码映射到设计的视觉模型。相比之下,Vue.js 为轻量级数据绑定 DSL 付出了代价,因此我们拥有一个可视化扫描的模板,并将逻辑封装到指令和过滤器中。
React 的另一个问题是,由于 DOM 更新完全委托给虚拟 DOM,因此当你实际上想要控制 DOM 本身时,这有点棘手(虽然理论上你可以,但当你这样做时,你实际上是在与库作对)。对于需要即时自定义 DOM 操作的应用程序,特别是具有复杂时间要求的动画,这可能会成为一个相当令人讨厌的限制。在这方面,Vue.js 允许更大的灵活性,并且有 多个使用 Vue.js 构建的 FWA/Awwwards 获奖网站。
一些额外的说明
React 团队在将 React 打造成一个平台无关的 UI 开发范式方面有着非常雄心勃勃的目标,而 Vue 则专注于为 Web 提供务实的解决方案。
React 由于其函数式特性,与函数式编程模式非常契合。但是,它也为初级开发人员和初学者带来了更高的学习门槛。在这方面,Vue 更容易上手并提高生产力。
对于大型应用程序,React 社区在状态管理解决方案方面做了很多创新,例如 Flux/Redux。Vue 本身并没有真正解决这个问题(React 核心也是如此),但状态管理模式可以很容易地用于类似的架构。Vue 有自己的状态管理解决方案,称为 Vuex,也可以 将 Redux 与 Vue 一起使用。
React 开发的趋势是将所有内容都放在 JavaScript 中,包括你的 CSS。已经出现了许多 CSS-in-JS 解决方案,但或多或少都存在自己的问题。最重要的是,它偏离了标准的 CSS 创作体验,并且使利用 CSS 社区中现有的工作变得非常尴尬。Vue 的 单文件组件 为你提供了组件封装的 CSS,同时仍然允许你使用你选择的预处理器。
Ember
Ember 是一个功能齐全的框架,旨在高度意见化。它提供了许多既定的约定,一旦你熟悉了它们,它就可以使你非常高效。但是,这也意味着学习曲线很高,灵活性受到影响。当你试图在意见化的框架和一组松散耦合的工具之间进行选择时,这是一个权衡。后者为你提供了更多自由,但也要求你做出更多架构决策。
也就是说,将 Vue.js 核心与 Ember 的模板和对象模型层进行比较可能更好。
Vue 在普通 JavaScript 对象上提供非侵入式响应性,以及完全自动的计算属性。在 Ember 中,你需要将所有内容包装在 Ember 对象中,并为计算属性手动声明依赖项。
Vue 的模板语法利用了 JavaScript 表达式的全部功能,而 Handlebars 的表达式和助手语法相比之下非常有限。
在性能方面,即使在 Ember 2.0 中的最新 Glimmer 引擎更新之后,Vue 的性能也远远超过 Ember。Vue 自动批处理更新,而在 Ember 中,你需要在性能关键的情况下手动管理运行循环。
Polymer
Polymer 是另一个由 Google 赞助的项目,事实上,它也是 Vue.js 的灵感来源。Vue.js 的组件可以与 Polymer 的自定义元素进行松散比较,两者都提供非常相似的开发风格。最大的区别是 Polymer 是建立在最新的 Web Components 功能之上的,并且需要非凡的 polyfill 才能在不支持这些功能的浏览器中工作(性能下降)。相比之下,Vue.js 在 IE9 及更高版本中无需任何依赖项即可工作。
此外,在 Polymer 1.0 中,团队确实限制了其数据绑定系统,以弥补性能问题。例如,Polymer 模板中支持的唯一表达式是布尔否定和单个方法调用。它的计算属性实现也不够灵活。
最后,在部署到生产环境时,Polymer 元素需要通过一个名为 vulcanizer 的 Polymer 专用工具进行捆绑。相比之下,单个文件 Vue 组件可以利用 Webpack 生态系统提供的一切,因此您可以在 Vue 组件中轻松使用 ES6 和任何您想要的 CSS 预处理器。
Riot
Riot 2.0 提供了类似的基于组件的开发模型(在 Riot 中称为“标签”),具有最小且设计精美的 API。我认为 Riot 和 Vue 在设计理念上有很多共同点。然而,尽管比 Riot 重一些,但 Vue 确实提供了一些比 Riot 显著的优势。
- 真正的条件渲染(Riot 渲染所有 if 分支,只是显示/隐藏它们)
- 更强大的路由器(Riot 的路由 API 太简陋了)
- 更成熟的工具支持(参见 webpack + vue-loader)
- 过渡效果系统(Riot 没有)
- 更好的性能。(实际上,Riot 使用脏检查而不是虚拟 DOM,因此会遇到与 Angular 相同的性能问题。)