You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We covered a lot of ground on the podcast, but most things we talked about could benefit from some code snippets to illustrate their similaraties and differences.
This post is a succinct rundown of most Vue features, and how I would write them with React in 2019 with hooks.
这篇文章简明扼要地概述了 Vue 的大多数特性,以及我将如何在2019年用钩子写它们。
Did I miss anything? Are there other comparisons you’d like to see? Or do you just want to share your thoughts about Vue or React? Talk to me on Twitter!
Vue uses HTML strings with some custom directives for templating. They recommend using .vue files to seperate the templates and script (and optionally styles).
Vue 使用 HTML 字符串和一些用于模板的自定义指令。 他们建议使用。 Vue 文件分离模板和脚本(和可选样式)。
<!-- Greeter.vue --><template><p>Hello, {{ name }}!</p></template><script>exportdefault{props: ['name']};</script>
React uses JSX, which is an extension of ECMAScript.
使用 JSX,它是 ECMAScript 的一个扩展。
exportdefaultfunctionGreeter({ name }){return<p>Hello, {name}!</p>;}
Conditional rendering
条件呈现
React alternative: Logical && operator, ternary statements, or early returns
反应替代: 逻辑 & & 操作符,三元语句,或早期返回
Vue uses v-if, v-else and v-else-if directives to conditionally render parts of a template.
Vue 使用 v-if、 v-else 和 v-else-if 指令有条件地呈现模板的部分。
<!-- Awesome.vue --><template><article><h1v-if="awesome">Vue is awesome!</h1></article></template><script>exportdefault{props: ['awesome']};</script>
React doesn’t support directives, so you need to use the language to conditionally return parts of a template.
React 不支持指令,因此需要使用该语言有条件地返回模板的部分内容。
The && operator provides a succinct way to write an if statement.
& 运算符提供了一种简洁的方式来编写 if 语句。
exportdefaultfunctionAwesome({ awesome }){return(<article>{awesome&&<h1>React is awesome!</h1>};
</article>);}
If you need an else clause, use a ternary statement instead.
如果需要 else 子句,可以使用三元语句。
exportdefaultfunctionAwesome({ awesome }){return(<article>{awesome ? (<h1>React is awesome!</h1>) : (<h1>Oh no 😢</h1>)};
</article>}
You could also opt to keep the two branches completely separated, and use an early return instead.
您还可以选择将两个分支完全分离,并使用提前返回代替。
exportdefaultfunctionAwesome({ awesome }){if(!awesome){return(<article><h1>Oh no 😢</h1></article>);}return(<article><h1>React is awesome!</h1></article>);}
List rendering
列表呈现
React alternative: Array.map
反应方式: ary.map
Vue uses the v-for directive to loop over arrays and objects.
v-model is a convenient Vue directive that combines passing down a value prop with listening to an input event. This makes it look like Vue does two-way binding, while it’s still just “props down, events up” under the hood.
If performance is a concern, the computation can be wrapped in a useMemo hook. useMemo requires a callback that returns a computed result, and an array of dependencies.
Vue has a methods option to declare functions that can be used throughout the component.
Vue 有一个方法选项来声明可以在整个组件中使用的函数。
<!-- ImportantButton.vue --><template><buttononClick="doSomething">
Do something!
</button></template><script>exportdefault{methods: {doSomething(){// ...}}};</script>
In React you can declare plain functions inside our component.
在响应中,您可以在组件中声明普通函数。
exportdefaultfunctionImportantButton(){functiondoSomething(){// ...}return(<buttononClick={doSomething}>
Do something!
</button>);}
Events
活动
React alternative: Callback props
反应: 回调道具
Events are essentially callbacks that are called when something happened in the child component. Vue sees events as a first-class citizen, so you can “listen” to them with @, which is shorthand for the v-ondirective.
With class components, React has a very similar API to Vue when it comes to the component lifecycle. With hooks, most lifecycle-related problems can be solved with useEffect. Effects and lifecycle methods are completely different paradigms, so they're hard to compare. In turn, this section is limited to a few practical examples, as effects deserve their own article.
With useEffect, you can declare a “side effect” that needs to run after a render. When you return a callback from useEffect, it will be invoked when the effect gets cleaned up. In this case, when the component is destroyed.
Similar to useMemo, useEffect accepts an array of dependencies as a second parameter.
与 usemo 类似,useEffect 接受依赖项数组作为第二个参数。
Without any specified dependencies, the effect will run after every render, and will clean up before every next render. This functionality is similar to a combination of mounted, updated, beforeUpdate and beforeDestroy.
useEffect(()=>{// Happens after every renderreturn()=>{// Optional; clean up before next render};});
If you specify that the effect has no dependencies, the effect will only run when the component renders the first time, because it has no reason to update. This functionality is similar to a combination of mounted, and beforeDestroyed.
useEffect(()=>{// Happens on mountreturn()=>{// Optional; clean up before unmount};},[]);
If you specify a dependency, the effect will only run when the dependency changes. We’ll get back to this in the watchers section.
如果指定依赖项,则只有在依赖项更改时才会运行效果。 我们将在观察者部分回到这个问题。
const[count,setCount]=useState(0);useEffect(()=>{// Happens when `count` changesreturn()=>{// Optional; clean up when `count` changed};},[count]);
Trying to directly translating lifecycle hooks to useEffect calls is generally a bad idea. It’s better to rethink things as a set of declarative side effects. When the effect is called is an implementation detail.
Watchers are conceptually similar to lifecycle hooks: “When X happens, do Y”. Watchers don’t exist in React, but you can achieve the same with useEffect.
观察者在概念上类似于生命周期挂钩:"当 x 发生时,做 y"。 观察者并不存在于反应中,但是你可以通过使用效果达到同样的效果。
<!-- RedParagraph.vue --><template><pstyle="color: red"><slot/></p></template>
export default function RedParagraph({ children }) {
return (
<pstyle={{color: 'red' }}>
{children}
</p>
);
}
Since “slots” are just props in React, we don’t need to declare anything in our templates. We can just accept props with JSX, and render them where and when we want.
<!-- Layout.vue --><template><divclass="flex"><sectionclass="w-1/3"><slotname="sidebar" /></section><mainclass="flex-1"><slot/></main></div></template><!-- In use: --><layout><template#sidebar><nav>...</nav></template><template#default><post>...</post></template></layout>
export default function RedParagraph({ sidebar, children }) {
return (
<divclassName="flex"><sectionclassName="w-1/3">
{sidebar}
</section><mainclassName="flex-1">
{children}
</main></div>
);
}
// In use:
return (
<Layoutsidebar={<nav>...</nav>}><Post>...</Post></Layout>
);
Vue has scoped slots to pass data to the slot that will be rendered. The key part of scoped slots is will be rendered.
Vue 已经确定了狭槽的作用域,以便将数据传递给将要呈现的狭槽。 将呈现作用域狭槽的关键部分。
Regular slots are rendered before they get passed to the parent component. The parent component then decides what to do with the rendered fragment.
常规插槽在传递给父组件之前被呈现。 然后,父组件决定如何处理呈现的片段。
Scoped slots can’t be rendered before the parent component, because they rely on data they’ll receive from the parent component. In a way, scoped slots are lazily evaluated slots.
Lazily evaluating something in JavaScript is rather straightforward: wrap it in a function and call it when needed. If you need a scoped slot with React, pass a function that will render a template when called.
For a scoped slots, we can once again use children, or any other prop for named scoped slots. However, we’ll pass down a function instead of declaring a template.
React doesn’t have any built in transition utilities. If you’re looking for something similar to Vue, a library that doesn’t actually animates anything but orchestrates animations with classes, look into react-transition-group.
For the past three years, I’ve been using both React and Vue in different projects, ranging from smaller websites to large scale apps.
在过去的三年里,我一直在不同的项目中使用 React 和 Vue,范围从小型网站到大型应用程序。
Last month I wrote a post about why I prefer React over Vue. Shortly after I joined Adam Wathan on Full Stack Radio to talk about React from a Vue developer’s perspective.
上个月,我写了一篇关于为什么我更喜欢 React 而不是 Vue 的帖子。 在我加入 Adam Wathan 的全栈收音机之后不久,我从一个 Vue 开发者的角度讨论了 React。
We covered a lot of ground on the podcast, but most things we talked about could benefit from some code snippets to illustrate their similaraties and differences.
我们在播客中涉及了很多内容,但是我们讨论的大多数内容都可以从一些代码片段中获益,以说明它们的相似之处和不同之处。
This post is a succinct rundown of most Vue features, and how I would write them with React in 2019 with hooks.
这篇文章简明扼要地概述了 Vue 的大多数特性,以及我将如何在2019年用钩子写它们。
Did I miss anything? Are there other comparisons you’d like to see? Or do you just want to share your thoughts about Vue or React? Talk to me on Twitter!
我错过什么了吗? 你还想看到其他的比较吗? 或者你只是想分享你关于 Vue 的想法或者做出反应? 在推特上和我聊天吧!
Table of contents
目录
Templates
模板
React alternative: JSX
反应备选: JSX
Vue uses HTML strings with some custom directives for templating. They recommend using
.vue
files to seperate the templates and script (and optionally styles).Vue 使用 HTML 字符串和一些用于模板的自定义指令。 他们建议使用。 Vue 文件分离模板和脚本(和可选样式)。
React uses JSX, which is an extension of ECMAScript.
使用 JSX,它是 ECMAScript 的一个扩展。
Conditional rendering
条件呈现
React alternative: Logical && operator, ternary statements, or early returns
反应替代: 逻辑 & & 操作符,三元语句,或早期返回
Vue uses
v-if
,v-else
andv-else-if
directives to conditionally render parts of a template.Vue 使用 v-if、 v-else 和 v-else-if 指令有条件地呈现模板的部分。
React doesn’t support directives, so you need to use the language to conditionally return parts of a template.
React 不支持指令,因此需要使用该语言有条件地返回模板的部分内容。
The
&&
operator provides a succinct way to write anif
statement.& 运算符提供了一种简洁的方式来编写 if 语句。
If you need an
else
clause, use a ternary statement instead.如果需要 else 子句,可以使用三元语句。
You could also opt to keep the two branches completely separated, and use an early return instead.
您还可以选择将两个分支完全分离,并使用提前返回代替。
List rendering
列表呈现
React alternative: Array.map
反应方式: ary.map
Vue uses the
v-for
directive to loop over arrays and objects.Vue 使用 v-for 指令对数组和对象进行循环。
With React, you can “map” the array to a set of elements using the built in
Array.map
function.使用 React,您可以使用内置的 Array.map 函数将数组"映射"到一组元素。
Iterating objects is a bit trickier. Vue allows you to use the same
v-for
directive for keys & values.迭代对象有点棘手。 Vue 允许您对键和值使用相同的 v- 指令。
I like to use the built in
Object.entries
function with React to iterate over objects.我喜欢在 React 中使用内置的 Object.entries 函数来迭代对象。
Class and style bindings
类和样式绑定
React alternative: Manually pass props
反应方式: 手动传球
Vue automatically binds
class
andstyle
props to the outer HTML element of a component.Vue 自动将类和样式道具绑定到组件的外部 HTML 元素。
With React, you need to manually pass
className
andstyle
props. Note thatstyle
must be an object with React, strings are not supported.使用 React,您需要手动传递 className 和 style props。 注意,样式必须是具有 React 的对象,不支持字符串。
If you want to pass down all remaining props, the object rest spread operator comes in handy.
如果你想传递所有剩余的道具,对象休息传播运算符派上用场。
If you miss Vue’s excellent
class
API, look into Jed Watson’s classnameslibrary.如果您错过了 Vue 优秀的类 API,请查看 Jed Watson 的类名库。
Props
道具
React alternative: Props
反应替代品: 道具
Props behave pretty much the same way in React as Vue. One minor difference: React components won’t inherit unknown attributes.
道具在 React as Vue 中的表现几乎相同。 一个小小的区别: 反应组件不会继承未知的属性。
Using expressions as props in Vue is possible with a
:
prefix, which is an alias for thev-bind
directive. React uses curly braces for dynamic values.在 Vue 中使用表达式作为 props 可以使用: 前缀,这是 v-bind 指令的别名。 React 为动态值使用花括号。
Data
数据
React alternative: The useState hook
反应方案: 美国房地产挂钩
In Vue the
data
option is used to store local component state.在 Vue 中,数据选项用于存储本地组件状态。
React exposes a
useState
hook which returns a two-element array containing the current state value and a setter function.React 公开一个 useState 挂钩,该挂钩返回一个包含当前状态值和 setter 函数的两元素数组。
You can choose whether you prefer to distribute state between multiple
useState
calls, or keep it in a single object.您可以选择是在多个 useState 调用之间分发状态,还是将其保存在单个对象中。
v-model
V 型
v-model
is a convenient Vue directive that combines passing down avalue
prop with listening to aninput
event. This makes it look like Vue does two-way binding, while it’s still just “props down, events up” under the hood.V-model 是一个方便的 Vue 指令,它结合了传递值支撑和倾听输入事件。 这使它看起来像 Vue 做双向绑定,而它仍然只是"道具下来,事件上来"的引擎盖下。
Vue expands the
v-model
directive to the following:Vue 将 v-model 指令扩展为以下内容:
React doesn’t have a
v-model
equivalent. You always need to be explicit:反应并没有 v-model 的等价物。 你总是需要明确:
Computed properties
计算属性
React alternative: Variables, optionally wrapped in useMemo
反应替代: 变量,可以选择包装在 usemo 中
Vue has computed properties for two reasons: to avoid mixing logic and markup in templates, and to cache complex computations in a component instance.
Vue 使用计算属性有两个原因: 避免在模板中混合使用逻辑和标记,以及在组件实例中缓存复杂的计算。
Without computed properties:
没有计算属性:
With React, you can extract the computation from the template by assigning the result to a variable.
使用 React,您可以通过将结果分配给一个变量来从模板中提取计算。
If performance is a concern, the computation can be wrapped in a
useMemo
hook.useMemo
requires a callback that returns a computed result, and an array of dependencies.如果性能是一个问题,那么计算可以包装在 usemo 钩子中。 Usemo 需要返回计算结果的回调和依赖项数组。
In the following example,
reversedMessage
will only be recomputed if themessage
dependency changes.在下面的示例中,只有在消息依赖关系发生更改时,才会重新计算 reversedMessage。
Methods
方法
React alternative: Functions
反应替代: 功能
Vue has a
methods
option to declare functions that can be used throughout the component.Vue 有一个方法选项来声明可以在整个组件中使用的函数。
In React you can declare plain functions inside our component.
在响应中,您可以在组件中声明普通函数。
Events
活动
React alternative: Callback props
反应: 回调道具
Events are essentially callbacks that are called when something happened in the child component. Vue sees events as a first-class citizen, so you can “listen” to them with
@
, which is shorthand for thev-on
directive.事件本质上是在子组件中发生事件时调用的回调。 Vue 将事件视为一个第一类物件,因此您可以使用@"listen"来"listen"它们,@是 v-on 指令的简写。
Events don’t have any special meaning in React, they’re just callback props will be called by the child component.
事件在 React 中没有任何特殊含义,它们只是由 child 组件调用的回调道具。
Event modifiers
事件修饰符
React alternative: Higher order functions if you really want
反应替代: 高阶函数,如果你真的想要
Vue has a few modifiers like
prevent
andstop
to change the way an event is handled without touching it’s handler.Vue 有一些修饰符,比如 prevent 和 stop,可以在不接触事件处理程序的情况下更改事件的处理方式。
There’s no modifier syntax in React. Preventing defaults and stopping propagation is mostly handled in the callback.
在 React 中没有修饰语语法。 预防缺省值和停止传播主要是在回调中处理的。
If you really want to have something modifier-like, you could use a higher order function.
如果你真的想要一些类似修饰符的东西,你可以使用一个高阶函数。
Lifecycle methods
生命周期方法
React alternative: The useEffect hook
反应方式: 使用效果钩子
DISCLAIMER
免责声明
With class components, React has a very similar API to Vue when it comes to the component lifecycle. With hooks, most lifecycle-related problems can be solved with
useEffect
. Effects and lifecycle methods are completely different paradigms, so they're hard to compare. In turn, this section is limited to a few practical examples, as effects deserve their own article.对于类组件,当涉及到组件生命周期时,React 有一个与 Vue 非常类似的 API。 使用钩子,大多数与生命周期相关的问题可以使用 useEffect 来解决。 效果和生命周期方法是完全不同的范例,所以它们很难比较。 反过来,这一节仅限于几个实际例子,因为效果值得自己的文章。
A common case for lifecycle methods is to set up and tear down third party libraries.
生命周期方法的一个常见案例是建立和拆除第三方库。
With
useEffect
, you can declare a “side effect” that needs to run after a render. When you return a callback fromuseEffect
, it will be invoked when the effect gets cleaned up. In this case, when the component is destroyed.使用 useEffect,你可以声明一个需要在渲染后运行的"副作用"。 当你从 useEffect 返回一个回调函数时,它会在效果被清除时被调用。 在本例中,当组件被销毁时。
This looks similar to registering a
beforeDestroy
listener inmounted
in a Vue component.这看起来类似于在 Vue 组件中的挂载中注册 beforeDestroy 侦听器。
Similar to
useMemo
,useEffect
accepts an array of dependencies as a second parameter.与 usemo 类似,useEffect 接受依赖项数组作为第二个参数。
Without any specified dependencies, the effect will run after every render, and will clean up before every next render. This functionality is similar to a combination of
mounted
,updated
,beforeUpdate
andbeforeDestroy
.如果没有任何指定的依赖项,效果将在每次渲染之后运行,并在每次下一次渲染之前清除。 此功能类似于挂载、更新、 beforeUpdate 和 beforeDestroy 的组合。
If you specify that the effect has no dependencies, the effect will only run when the component renders the first time, because it has no reason to update. This functionality is similar to a combination of
mounted
, andbeforeDestroyed
.如果指定该效果没有依赖项,则该效果只会在组件第一次呈现时运行,因为它没有理由进行更新。 这个功能类似于挂载和 beforeDestroyed 的组合。
If you specify a dependency, the effect will only run when the dependency changes. We’ll get back to this in the watchers section.
如果指定依赖项,则只有在依赖项更改时才会运行效果。 我们将在观察者部分回到这个问题。
Trying to directly translating lifecycle hooks to
useEffect
calls is generally a bad idea. It’s better to rethink things as a set of declarative side effects. When the effect is called is an implementation detail.尝试直接将生命周期挂钩转换为 useEffect 调用通常是一个坏主意。 最好把事情当作一系列宣示性的副作用来重新思考。 当调用效果时,是一个实现细节。
As Ryan Florence sums it up:
正如瑞安•弗洛伦斯(Ryan Florence)总结的:
Watchers
守望者
React alternative: The useEffect hook
反应方式: 使用效果钩子
Watchers are conceptually similar to lifecycle hooks: “When X happens, do Y”. Watchers don’t exist in React, but you can achieve the same with
useEffect
.观察者在概念上类似于生命周期挂钩:"当 x 发生时,做 y"。 观察者并不存在于反应中,但是你可以通过使用效果达到同样的效果。
Note that
useEffect
will also run in the first render. This is the same as using theimmediate
parameter in a Vue watcher.注意,useEffect 也会在第一次渲染中运行。 这与在 Vue 观察器中使用立即参数相同。
If you don’t want the effect to run on the first render, you’ll need to create a
ref
to store whether or not the first render has happened yet or not.如果你不想让效果在第一次渲染时运行,你需要创建一个 ref 来存储第一次渲染是否已经发生。
Slots & scoped slots
槽和作用域槽
React alternative: JSX props or render props
反应替代: JSX 道具或渲染道具
If you render a template inside between a component’s opening and closing tags, React passes it as a
children
prop.如果在组件的开始标记和结束标记之间渲染一个模板,React 将其作为一个子标记传递给它。
With Vue, you need to declare a
<slot />
tag where inner contents belong. With React, you render thechildren
prop.使用 Vue 时,您需要在内部内容所属的位置声明一个 slot / tag。 用反击,你给孩子们提供支持。
Since “slots” are just props in React, we don’t need to declare anything in our templates. We can just accept props with JSX, and render them where and when we want.
因为"插槽"只是 React 中的道具,所以我们不需要在模板中声明任何东西。 我们可以使用 JSX 接受道具,然后在需要的时间和地点渲染它们。
Vue has scoped slots to pass data to the slot that will be rendered. The key part of scoped slots is will be rendered.
Vue 已经确定了狭槽的作用域,以便将数据传递给将要呈现的狭槽。 将呈现作用域狭槽的关键部分。
Regular slots are rendered before they get passed to the parent component. The parent component then decides what to do with the rendered fragment.
常规插槽在传递给父组件之前被呈现。 然后,父组件决定如何处理呈现的片段。
Scoped slots can’t be rendered before the parent component, because they rely on data they’ll receive from the parent component. In a way, scoped slots are lazily evaluated slots.
作用域插槽不能在父组件之前呈现,因为它们依赖于从父组件接收的数据。 在某种程度上,限定作用域的槽被延迟计算。
Lazily evaluating something in JavaScript is rather straightforward: wrap it in a function and call it when needed. If you need a scoped slot with React, pass a function that will render a template when called.
懒惰地在 JavaScript 中计算一些东西是相当直接的: 将它包装在一个函数中,并在需要时调用它。 如果需要使用 React 的作用域插槽,请传递一个函数,该函数将在调用时呈现模板。
For a scoped slots, we can once again use
children
, or any other prop for named scoped slots. However, we’ll pass down a function instead of declaring a template.对于有作用域的狭槽,我们可以再次使用子狭槽或任何其他道具来命名有作用域的狭槽。 但是,我们将传递一个函数,而不是声明一个模板。
Provide / inject
提供 / 注入
React alternative: createContext and the useContext hook
反应替代: createContext 和 useContext 钩子
Provide / inject allows a component to share state with its subtree. React has a similar feature called context.
提供 / 注入允许组件与其子树共享状态。 有一个类似的特性叫做上下文。
Custom directives
自定义指令
React alternative: Components
反应替代: 组件
Directives don’t exist in React. However, most problems that directives solve can be solved with components instead.
指令并不存在于反应中。 然而,指令解决的大多数问题都可以通过组件来解决。
Transitions
过渡期
React alternative: Third party libraries
反应: 第三方库
React doesn’t have any built in transition utilities. If you’re looking for something similar to Vue, a library that doesn’t actually animates anything but orchestrates animations with classes, look into react-transition-group.
没有任何内置的转换工具。 如果您正在寻找与 Vue 类似的东西,那么您可以查看 react-transition-group,这个库实际上并不制作任何动画,而是用类编排动画。
原文
The text was updated successfully, but these errors were encountered: