英文:Harry Wolff,翻译:前端大全 / v2li前端
在过去的 5 年中,我一直是一名 React 工程师。我爱 React,我爱开发 React 应用。我认为它是现存最好的 UI 框架之一。react
然而,React 在这个领域中有一些竞争对手,其中最大的就是 Vue.js。浏览器
我曾玩过一阵 Vue.js,但我认为那时的经验已通过时了。由于我将要深刻研究 Vue.js 的工做原理以及了解它是如何让个人工做变得更简单。app
在深刻研究 Vue.js 文档并使用以后(注意:我绝对不是 Vue.js 的专家),我惊奇地发现有些方面 Vue.js 甚至比 React 作得更好。框架
最后,我但愿 React 能受到 Vue.js 的启发而且也开始这么作。ide
一、不一样的理念
Vue.js 和 React 之间的一个主要区别是它们对本身的定位不一样。函数
从它们官网直观来看,React 把本身描述为 “一个用于构建用户界面的 JavaScript 库”,而 Vue.js 则把本身描述为“渐进式 JavaScript 框架”。学习
React 是一个库,而 Vue.js 是一个框架。我认为从不少方面来讲,这是致使这些 UI 框架在执行方式上有所不一样的根本缘由。this
我想强调这一点,以便您在阅读本文时随时牢记这一点。 从历史上看,库和框架都专一于让它们的工做表现得更出色,但框架的要求和提供的能力更全面详尽,而库则更少更轻量。翻译
二、单文件组件
Vue 和 React 都有用来建立 UI 的组件。
组件一般由 3 部分组成:
UI (HTML)
行为 (JavaScript)
Vue.js 的理念是使用单文件组件,用一种开箱即用的方式来编写涵盖全部 3 个部分的组件。
看起来像这样:
<template> <p>{{ greeting }} World!</p> </template> <script> module.exports = { data() { return { greeting: 'Hello', }; }, }; </script> <style scoped> p { font-size: 2em; text-align: center; } </style>
即使你不是一个 Vue.js 的工程师也能够理解这里的代码。
React 组件提供了开箱即用的 UI 和 行为部分,可是样式在很大程度上不受限制:
import React, { useState } from 'react'; function Button() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> Current count: {count} <br /> Click me </button> ); }
固然了,React 有一个很是活跃的社区,因此若是你想包含样式,能够轻松使用 Emotion 或 Styled Components 来填补样式的空缺,可是:
它们是非内置的;
这正好与默认提供了这些的 Vue.js 相反。
三、官方支持的相关库
任何足够大且复杂的 UI 应用都须要两个附加功能的支持:
路由
Vue.js 官方支持的库分别覆盖了这两个场景: Vue Router 和 Vuex 。
这些库明确地在 Vue.js 文档中说起,而且由 Vue.js 核心组开发和维护。这太神奇了。
它为刚使用 Vue.js 的工程师提供了解决问题的明确方法,并让他们相信这些库是长期维护的。
拥有第一方支持的库并不会限制社区解决方案,但确实为新用户提供了入门解决方案
四、风格指南
嗯,我很是但愿 React 也有风格指南,在阅读本节以前,请单击连接并浏览Vue.js的样式指南。
它回答了不少 Vue.js 新手可能遇到的问题,并提供了如何编写 “适当的” 和易于访问的 Vue.js 的最佳实战。
它分享了通过实战检验的以及社区中的最佳实践和模式。
最重要的是:它是由 Vue.js 官方维护和支持的!这太棒了!
五、类和样式绑定
如上所述,Vue.js 内置了对样式的支持。此外,Vue.js 本质上是内置 classNames 的。
Classnmes 是一个很棒的库,能够方便地链接和动态构造应用于 HTML 元素的 CSS 类名。
而在 React 中,你须要知道这个库,而后安装它。
在 Vue.js 中,这只是另外一个内置特性:参考文档:
Vue.js 模板:
<div class="static" :class="{ active: isActive, 'text-danger': hasError }" ></div>
data 内容:
data() { return { isActive: true, hasError: false } }
渲染出的 UI:
<div class="static active"></div>
有这个内置项真好。
Vue.js 进一步支持内联样式。Vue.js 和 React 同样,都支持内联样式,可是 Vue.js 比 React 更棒的地方就是它可以自动为须要的 CSS 加上前缀。
参考文档:
当使用 :style 时,须要添加浏览器引擎前缀的 CSS 属性,拿 transform 举例,Vue.js 会自动侦测并添加相应的前缀。
真正显示框架控制本身的模板语法的优点。
六、插槽
React 中一切都是 prop。
若是要在 React 组件中渲染多个子节点,只需添加多个 prop:
function Nav({ left, right }) { return ( <nav> <div className="left">{left}</div> <div className="right">{right}</div> </nav> ); } function App() { return ( <main> <Nav left={<Logo />} right={<UserDropdown />} /> </main> ); }
但若是内部内容边庞大以后,虽然能很好运行,但有一点尴尬。
Vue.js 采用了插槽的方法,我认为它的 API 更简洁。
<!-- A Vue.js component template named "base-layout" --> <div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> <!-- When "base-layout" is used --> <base-layout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <template v-slot:default> <p>A paragraph for the main content.</p> <p>And another one.</p> </template> <template v-slot:footer> <p>Here's some contact info</p> </template> </base-layout>
Vue.js 使用插槽(受Web Component 规则草案的启发)清楚地指明内容在组件内部的位置。
Vue.js 为反复执行的任务提供了捷径。在这种状况下,可使用插槽来简化上面的示例:
<base-layout> <template #header> <h1>Here might be a page title</h1> </template> <template #default> <p>A paragraph for the main content.</p> <p>And another one.</p> </template> <template #footer> <p>Here's some contact info</p> </template> </base-layout>
七、指令修饰符
我认为 Vue.js 指令修饰符的功能真的很酷。
在讨论指令修饰符以前,让我快速介绍一下指令是什么。
指令 v- 是你在 Vue.js 模板中使用的“带有前缀的特殊属性”。
指令的做用是在表达式的值发生变化时以响应地方式将反作用施加到 DOM
例如:
// If "seen" variable is false then this p tag is not rendered <p v-if="seen">Now you see me</p>
针对事件地指令:
<!-- full syntax --> <a v-on:click="doSomething"> ... </a> <!-- shorthand --> <a @click="doSomething"> ... </a>
还有其余更多的指令。
指令还支持修饰符。
使用通用指令执行通用操做很开发友好。
对于事件处理指令(v-on),有不少修饰符:
<!-- the click event's propagation will be stopped --> <a @click.stop="doThis"></a> <!-- the submit event will no longer reload the page --> <form @submit.prevent="onSubmit"></form> <!-- modifiers can be chained --> <a @click.stop.prevent="doThat"></a> <!-- just the modifier --> <form @submit.prevent></form> ...and more!
若是你想在 React 中执行这样的操做,能够建立一个辅助函数或一个自定义组件。但与指令修饰符地方式相比并不简洁。
我很好奇是否有人能够开发一个 Babel JSX 超集,而后就能够编写以下代码了:
<form onSubmit.prevent={onSubmit} />
它将转换为:
React.createElement(form, { onSubmit: preventWrapper(onSubmit) });
这不在 React 的讨论范围内,但我仍然认为这会是一次生产效率地大提高。
还有更多的 Vue.js 修饰符。好比按键修饰符:
<!-- only call `submit()` when the `key` is `Enter` --> <input @keyup.enter="submit" /> <input @keyup.page-down="onPageDown" />
太酷了。
八、表单输入绑定
当将数据绑定到输入元素时,v-model 指令会有很是有趣的特性。
从文档中发现,v-model 内部使用了不一样的属性,并为不一样的输入元素发出不一样的事件:
text 和 textarea 元素使用 value 属性和 input 事件;
复选框和单选按钮使用 checked 属性和 change 事件;
这样作的好处是,您无需关心数据是如何同步的,您只需关心它是如何为你服务的。
让咱们比较一下 React 和 Vue.js 是如何进行绑定:
// Input //////// // React <input type="input" value={message} onChange={onChange} /> // Vue.js <input type="input" v-model="message" /> // Checkboxes and Radiobuttons //////// // React <input type="checkbox" checked={message != null} onChange={onChange} /> // Vue.js <input type="checkbox" v-model="message" /> // Select //////// // React <select value={message} onChange={onChange}> <option>A</option> </select> // Vue.js <select v-model="message"> <option>A</option> </select>
发现其中的不一样了吗?
如今,我要为 React 辩护了,React 鼓励(并要求)您学习学习数据实际是如何设置以及它是如何变化的。这意味着,若是您曾经用普通 JS 写过一个表单,您将更了解其运行原理。 与 Vue.js 不一样,后者帮您把这些特性都抽象出来了。
九、自定义指令
像任何好的框架同样,您能够在 Vue.js 中建立本身的自定义指令。
Vue.js 确实关注“代码重用和抽象的主要形式是组件”,但这里有一个使用自定义指令不错的例子,经过v-focus在 mount 时自动聚焦到元素上:
const app = Vue.createApp({}) // Register a global custom directive called `v-focus` app.directive('focus', { // When the bound element is mounted into the DOM... mounted(el) { // Focus the element el.focus() } }) <input v-focus />
在 React 中,你可能会编写一个自定义组件来完成相同的事情,但对于这种简单任务而言有些重
十、用 TypeScript 编写
最后,Vue.js 最近正在用 TypeScript 重写。
这意味着它们对 TypeScript 支持都是一流的,由于框架自己是就是用 TypeScript 编写的。
其实 React 用什么编写并不重要,我也不认为它有什么太大的区别,但看到 Vue.js 也用 TypeScript 编写仍然是一件很不错事。
总结
我是要放弃 React 并开始专门使用 Vue.js 吗?不,我仍然很是喜欢做为“库”的 React 而且坦率地讲,我已经很精通编写 React 程序了。
可是,我很但愿看到 React 能从 Vue.js 中汲取一些灵感并整合到其中,若是只能从本文中提到的几个点中选择一个,我绝对选风格指南。我很期盼能看到 React 有一个官方支持和维护的风格指南。
但愿我能让你看到一些你不知道 Vue.js!我很确信本身真的很喜欢 Vue.js 的哲学!