react和vue
As for React and Vue.js, there’s enough said about them on the net. Svelte is a relatively young framework, so we’ll just add a couple of words about it. The most striking difference from the others is that while having most of their benefits, it has:
至于React和Vue.js,网上有足够的评论。 Svelte是一个相对较年轻的框架,因此我们只在其中添加一些文字。 与其他人最显着的区别是,尽管拥有其他人的大部分利益,但它具有:
- No virtual DOM 没有虚拟DOM
- No runtime 没有运行时间
- Unique “reactivity” 独特的“React性”
There is no svelte.js
to import — it compiles user code to plain JavaScript instead. It makes Svelte faster¹,² than the other two, and easier to integrate into an existing project as it has basically zero overhead (smallest bundle size² according to the RealWorld framework comparison of 2020).
没有要导入的svelte.js
,而是将用户代码编译为纯JavaScript。 与Svelte相比,它使Svelte 更快 1,2,3,并且由于其基本开销为零(根据2020年RealWorld框架比较, 最小的装束²),更易于集成到现有项目中。
Another thing that makes Svelte so fast is that it tracks interdependencies of the variables which helps minimizing the number of DOM updates.
使得Svelte如此之快的另一件事是,它跟踪变量的相互依赖性,这有助于最大程度地减少DOM更新的次数。
Last month Svelte received a long-awaited TypeScript support.
上个月,Svelte获得了期待已久的TypeScript支持 。
Yet as for the infrastructure, it is still one step behind React and Vue (eg syntax highlighting in major libraries/editors, debug tools, number of third-party libraries, etc).
但是对于基础架构,它仍然比React和Vue落后一步(例如,主要库/编辑器中的语法突出显示,调试工具,第三方库的数量等)。
In this article, I’ll describe the basic functionality and provide a simple linked selects app written in all the three frameworks as an example.
在本文中,我将描述基本功能,并提供一个以所有三个框架编写的简单链接选择应用程序为例。
1.变量 (1. Variables)
The most frequently used feature of the template system — variable substitution — is pretty similar in all of the three frameworks:
模板系统最常用的功能(变量替换)在所有三个框架中都非常相似:
2.有条件的 (2. Conditionals)
Here’s what a simple conditional looks like:
这是一个简单的条件如下所示:
React³ has no template language as such by design. It relies on the native JavaScript expressions (logical AND, in this particular case) for constructing the HTML from bits and pieces. The convenience comes from the usage of JSX, an extension of JavaScript that allows us to treat HTML tags as first-class citizens.
根据设计, React³没有模板语言。 它依靠本机JavaScript表达式(在这种特殊情况下为逻辑AND)来一点一点地构造HTML。 便利来自JSX的使用, JSX是JavaScript的扩展,允许我们将HTML标签视为一流的公民。
Vue.js⁴ has a template system which lives in the tag attributes (eg v-if
), as inherited from Angular.
Vue.js⁴具有一个模板系统,该模板系统位于从Angular继承的标签属性(例如v-if
)中。
The template language of Svelte⁵ is more readable and reminds us of the Django template language⁶. Having two different brace types — opening {# }
and closing {/ }
— looks more cryptic than one brace type {% %}
in Django, but requires fewer keystrokes yet keeping the readability at a high level.
Svelte⁵的模板语言更具可读性,使我们想起Django模板语言 ⁶。 与Django中的一种括号类型{% %}
相比,具有两种不同的括号类型(打开{# }
和结束{/ }
)看起来更神秘,但所需的击键次数却更少,但仍保持了较高的可读性。
The next one is the if-else
statement:
下一个是if-else
语句:
In React, it is most naturally expressed with the ternary operator. In Vue, the logic is again in the attributes, and at this point, it already becomes less evident which v-if
is supposed to match which v-else
. Svelte introduces the third type of curly braces — the “intermediate” ones, with the colon.
在React中,它最自然地用三元运算符表示。 在Vue中,逻辑再次出现在属性中,此时,已经变得不太明显了哪个v-if
应该与哪个v-else
相匹配。 Card.svelte(Svelte)用冒号介绍了第三种花括号-“中间”花括号。
The next statement is if-elif-else
. Using nested ternary operators in React is generally considered bad practice, so here’s an example with the immediately invoked function expression (IIFE). In Vue and Svelte, the syntax is consistent with the if
and if-else
statements:
下一个语句是if-elif-else
。 在React中使用嵌套三元运算符通常被认为是不好的做法,因此这是一个带有立即调用的函数表达式(IIFE)的示例。 在Vue和Svelte中,语法与if
和if-else
语句一致:
Yet this React code is too difficult to digest and is only given here for completeness. As suggested by u/sephg in the comments, in spite of the fact that trenary operator is generally frowned upon, when used with proper formatting, it can produce more readable code than IIFE:
然而,这个React代码太难于理解了,仅出于完整性的目的在此给出。 正如u / sephg在评论中所建议的那样,尽管通常不赞成使用三进制运算符,但是如果使用适当的格式,它可以产生比IIFE更具可读性的代码:
When the conditions or clauses get longer, both nested trenary operators and IIFEs become too cluttered. The immediate alternative — moving the conditionals out of the template to a dedicated variable, a named function or a separate component— is a counter-example of the separation of the code and templates that the Django template system is so keen on (it’s also the bone of contention that brought jinja2 templates⁷ to existence).
当条件或子句变长时,嵌套的三进制运算符和IIFE都变得过于混乱。 即时的替代方案-将条件从模板移出至专用变量,命名函数或单独的组件-是Django模板系统非常热衷的代码和模板分离的反例(也是使jinja2模板⁷成为现实的争论之骨)。
There are third-party components for React that provide the “If/Else” tags, “Choose/When” tags, etc. (e.g. jsx-control-statements), but they have rather strong limitations: no short-circuiting (all branches are evaluated no matter what), poor syntax highlighting, etc.
有一些React的第三方组件提供“ If / Else”标签,“ Choose / When”标签等(例如jsx-control-statements ),但是它们有很强的局限性:没有短路(所有分支)无论如何评估),语法突出显示不佳等。
If those four ways of writing React conditionals are not enough, there’s a collection of eight in this blog post⁸ of 2018, or of nine in this blog post⁹ of 2020. Most notable of them are Higher-Order Components (docs), the React name for Python decorators.
如果这四种编写React条件的方式还不够,那么本博客文章 ⁸2018年有八种,或者本博客文章 ⁹2020年中有九种。其中最著名的是高阶组件( docs ), Python装饰器的名称。
It is also worth noting that React and Vue.js templates are oriented at breaking the HTML in the “natural” places such as tags. If you apply the DRY principle to the example above, things start going south pretty quickly:
还值得注意的是,React和Vue.js模板旨在在“自然”位置(例如标签)破坏HTML。 如果将DRY原理应用于上面的示例,事情会很快开始向南发展:
…while Svelte doesn’t care about the boundaries, except that it doesn’t allow conditionals inside a tag (something Django is perfectly comfortable with), e.g.
…虽然Svelte不在乎边界, 但它不允许在标签内使用条件(Django非常满意),例如
The suggested workaround is to use js inside the attribute value (React-style):
建议的解决方法是在属性值(React样式)内使用js:
If the expression evaluates to null
or undefined
the attribute is not written to the HTML at all (use <input readonly={x && ‘readonly’}>
for boolean properties).
如果表达式的计算结果为null
或undefined
该属性根本不会写入HTML(对于布尔属性,请使用<input readonly={x && 'readonly'}>
)。
3.循环 (3. Loops)
Except in the case of React where map()
is used, the loop syntax is consistent with the conditionals:
除了在React中使用map()
的情况外,循环语法与条件一致:
All three frameworks provide an automatic iteration counter:
这三个框架都提供了一个自动迭代计数器:
Vue has a special syntax for looping over the objects:
Vue具有用于遍历对象的特殊语法:
And Svelte has an additional clause for empty sequences:
Svelte还有一个用于空序列的子句:
If the sequence of entries generated in a loop is expected to be modified afterward, all the compared frameworks provide means (React warns, Vue requires, Svelte doesn’t mind) for keying the items to properly track their evolution:
如果希望在循环中生成的条目顺序随后会被修改,则所有比较的框架都将提供方法(React警告,Vue 要求 ,Svelte不在乎),以便为这些项目设置关键以正确跟踪其演变:
In Svelte, both of those modifications can be combined with destructuring:
在Svelte中,这两种修改都可以与销毁相结合:
4.数据绑定 (4. Data Binding)
There’s a lot of magic happening in the tag attributes in all the three frameworks. I’ll only mention the most indispensable: the ones that glue the JavaScript variables to the DOM widget state.
在这三个框架中,标签属性中发生了很多魔术。 我仅提及最不可或缺的部分:将JavaScript变量粘贴到DOM小部件状态的那些。
There are two ways to bind a variable to a widget: one-way binding and two-way binding.
有两种将变量绑定到窗口小部件的方式:单向绑定和双向绑定。
One-way binding instructs the framework to update DOM whenever the variable changes, but not the other way around: User input will have no effect on the bound variable. React is more restrictive than Svelte here: User input has no effect at all, unless you write a handler to make the binding two-way.
单向绑定指示框架在变量更改时更新DOM,反之则相反:用户输入对绑定变量无效。 在这里,React比Svelte更具限制性:用户输入根本没有任何作用,除非您编写处理程序以双向进行绑定。
Two-way binding is more convenient: Both variable and DOM “feel” each other’s changes. For example, it allows us to lock together a pair of controls displaying the same value in different ways, e.g. a slider and an input box.
双向绑定更方便:变量和DOM都“感觉”彼此的更改。 例如,它允许我们将一对以不同方式显示相同值的控件锁定在一起,例如滑块和输入框。
Here’s the summary of the variable binding syntax:
以下是变量绑定语法的摘要:
React used to support two-way bindings, but as of today, the recommended way is to set up the binding manually the way it is described in the table above.
React用于支持双向绑定,但是从今天开始, 推荐的方法是按照上表中所述的方式手动设置绑定。
5.组件文件结构 (5. Component File Structure)
The frameworks have different ways of organizing code in the files with the components. In React, the JavaScript code is interwoven with the HTML, whereas the CSS lives in a separate file. In Vue.js, all three types of code are combined in a .vue single-file component. Svelte has a similar structure; just the order of the blocks is different.
框架具有使用组件来组织文件中的代码的不同方式。 在React中,JavaScript代码与HTML交织在一起,而CSS位于单独的文件中。 在Vue.js中,所有三种类型的代码都组合在.vue 单文件组件中 。 Card.svelte具有类似的结构 ; 只是块的顺序不同。
As a matter of fact the order of the blocks in Vue and Svelte is arbitrary. But when working in a team it is convenient to be consistent about the order and to have sensible defaults. This Vue block order is recommended by the Vue Style Guide. This Svelte order — by the official Svelte prettifier plugin but an alternative javascript-html-css order is also widely used.
实际上,Vue和Svelte中块的顺序是任意的。 但是,在团队中工作时,保持顺序一致并具有明智的默认设置很方便。 《 Vue样式指南》建议使用此Vue块顺序。 该Svelte命令-由Svelte Prettifier官方插件提供,但也广泛使用了替代javascript-html-css命令。
The nice thing about having the styles in the same file is that the CSS is organically encapsulated so that it only applies to the current component (vue, svelte). In React it is also possible — either with CSS modules, or with any of the CSS-in-js third party libs (here’s a list of 62 packages on GitHub to begin with).
在同一文件中包含样式的好处是CSS是有机封装的,因此仅适用于当前组件( vue , svelte )。 在React中,使用CSS模块或任何CSS-in-js第三方库(这是GitHub上62个软件包的清单 )也是可行的。
6.部分页面刷新 (6. Partial Page Refresh)
In Django, template rendering only happens once: The variables are substituted, the code is shipped to the front end and forgotten (the database queries and parts of a template can be cached, though). The main purpose of the front-end frameworks is to re-render the page (or, better yet, a part of the page) with the updated information with minimum or no interaction with the server.
在Django中,模板渲染仅发生一次:变量被替换,代码被传送到前端并被遗忘(尽管数据库查询和模板的一部分可以被缓存)。 前端框架的主要目的是使用与服务器之间的交互最少或没有交互的更新信息来重新呈现页面(或者更好的是页面的一部分)。
In React and Vue, in order to achieve partial page refresh, you break the template into components, distribute your variables between them (aka component state), and then, whenever a variable changes, the whole component gets re-rendered. Components can contain other components, and there are certain rules that describe what should happen to a parent or a child component to trigger the re-rendering of the current one.
在React和Vue中,为了实现部分页面刷新,您将模板分为多个组件,在它们之间分配变量(又称组件状态),然后,每当变量更改时,整个组件都会重新呈现。 组件可以包含其他组件,并且有某些规则描述了父组件或子组件应该发生什么,以触发当前组件的重新渲染。
In Svelte, components also exist, but they serve a different purpose (code reuse, data flow management, etc.). The basic block of page re-rendering is an expression in the curly braces (variable, conditional, loop, etc). Whenever a variable used in it changes, the block is re-rendered while the rest of the page stays intact! (Example)
在Svelte中,组件也存在,但是它们有不同的用途(代码重用,数据流管理等)。 页面重新渲染的基本块是花括号(变量,条件,循环等)中的表达式。 只要其中使用的变量发生变化,该块就会重新呈现,而页面的其余部分保持不变! ( 示例 )
7.示例应用程序:链接选择 (7. Example App: Linked Selects)
Let’s see how the information given above can be used in practice. Consider two select boxes, the second of which depends on the value selected in the first one:
让我们看看上面给出的信息如何在实践中使用。 考虑两个选择框,其中第二个取决于第一个选择的值:
The complete source code of these projects is available on GitHub¹¹.
这些项目的完整源代码可在GitHub上获得 。
Building the project with the default tools (React¹², Vue/cli¹³, Svelte¹⁴) and the default settings results in the following bundle sizes:
使用默认的工具构建项目( 阵营 ¹², Vue公司/ CLI ¹³, Card.svelte ¹⁴),并在下面的捆绑包大小的默认设置的结果:
The size difference comes from the fact that Svelte does not have a runtime; it only compiles and bundles the code it was given by the user.
大小上的差异来自Svelte没有运行时的事实。 它仅编译并捆绑用户提供的代码。
A hello world project size (such as this one) might not be a good estimate of how large a real-world project can grow up to. The RealWorld comparison of 2019 and 2020 confirms that it’s just the same with the bigger apps as well.
你好,一个世界项目的大小(例如这个)可能无法很好地估计一个现实项目的规模。 RealWorld对2019年和2020年的比较证实了大型应用程序也是如此。
There’s an interesting discussion of Svelte bundle size “Yes, but does it scale?¹³”.
关于Svelte捆绑包大小,有一个有趣的讨论:“ 是的,但是可以扩展吗? ¹³”。
8.结论 (8. Conclusion)
All three frameworks provide a convenient template language, but in different ways: React syntax is the most flexible one, as it allows you to interleave the JavaScript and HTML in any imaginable way; Svelte syntax is the most readable; Vue.js is the golden ratio between those two.
这三个框架都提供了一种方便的模板语言,但是使用了不同的方式:React语法是最灵活的一种,因为它允许您以任何可以想象的方式插入JavaScript和HTML。 苗条的语法最易读。 Vue.js是两者之间的黄金分割。
But in spite of apparent differences, conceptually the template syntax of the frameworks is pretty similar. The main difference is in the reactivity — how they react to changes in component state. There’s an excellent video about it called “Rethinking Reactivity”¹⁶ by Rich Harris, the creator of Svelte.
但是,尽管存在明显的差异,但是从概念上讲,框架的模板语法非常相似。 主要区别在于React性-它们对组件状态变化的React方式。 Card.svelte(Svelte)的创作者里奇·哈里斯(Rich Harris)拍摄了一段很棒的视频,叫做“ 重新思考React性 ”。
翻译自: https://medium.com/better-programming/react-vue-and-svelte-templates-side-by-side-4aa52cf3cf2
react和vue