介
我比较喜欢使用 Vue 来开发,所以有时会深入研究其功能和特性。通过这篇文章,向你们介绍十个很酷的窍门和技巧,以帮助大家成为更好的 Vue 开发者。
随着Vue 2.6的推出,已经引入了插槽的简写方式,之前简写可用于事件(例如,@click表示v-on:click事件)或冒号表示方式用于绑定(:src)。例如,如果有一个表格组件,则可以按以下方式使用此功能:
如果要在created或mounted方法中定义自定义事件侦听器或第三方插件,并且需要在beforeDestroy方法中将其删除以免引起任何内存泄漏,则可以使用此功能。使用$on(‘hook:’)方法,我们可以仅使用一种生命周期方法(而不是两种)来定义/删除事件。
你可能已经知道可以将props验证为原始类型,例如字符串,数字甚至对象。我们还可以使用自定义验证器,例如,如果要针对字符串列表进行验证:
Vue 2.6 的最酷功能之一是可以将指令参数动态传递给组件。假设有一个按钮组件,并且在某些情况下想监听单击事件,而在其他情况下想监听双击事件。这就是动态指令派上用场的地方了:
有时,我们不同路由共用某些时,如果在这些路由之间切换,则默认情况下,共享组件将不会重新渲染,因为Vue 出于性能原因会重用该组件。但是,如果我们仍然希望重新渲染这些组件,则可以通过在路由器视图组件中提供:key属性来实现重新渲染。
这是一个非常酷的功能,可将所有prop从父组件传递到子组件。如果我们有另一个组件的包装器组件,这将特别方便。因为,我们不必一个一个将prop传递给子组件,而是一次传递所有prop:
上面的可以代替下面的做法
如果子组件不在父组件的根目录下,则可以将所有事件侦听器从父组件传递到子组件,如下所示:
如果子组件位于其父组件的根目录下,则默认情况下它将获得那些组件,因此不需要此小技巧。
默认情况下,每个Vue实例都可以访问$createElement方法来创建和返回虚拟节点。例如,可以利用它在可以通过v-html指令传递的方法中使用标记。在函数组件中,可以将此方法作为渲染函数中的第一个参数访问。
由于Vue CLI 3默认支持使用JSX,因此现在(如果愿意)我们可以使用JSX编写代码(例如,可以方便地编写函数组件)。如果尚未使用Vue CLI 3,则可以使用babel-plugin-transform-vue-jsx获得JSX支持。
默认情况下,v-model是@input事件监听器和:value props上的语法糖。但是,我们可以在Vue组件中指定一个模型属性,以定义使用什么事件和值
希望这些窍门和技巧对你有所帮助,如果你也知道哪些技巧,欢迎留言。
原文:https://www.telerik.com/blogs/12-tips-and-tricks-to-improve-your-vue-projects
avaScript框架之间的终极性能之战
我在网上浏览时发现,两年多来我们没有一个不错的JavaScript框架性能大赛。因此,在2020年总结之前,让我们在将这些库相互抗衡中获得一些乐趣。
如何采用20个最受欢迎的JavaScript框架,并使用JS Framework Benchmark使其并驾齐驱?
免责声明:此比较在整个过程中很有趣,也可能具有教育意义。和往常一样,这里的每个库对于大多数事情来说都足够高效。如果有什么要强调的是,性能可以来自多种不同的技术。虽然您可以将其用作参考,但您应该独立验证各个用例的性能。您可以在这里找到最新的官方结果。如果您想进一步了解此基准测试的内容,请在此处发布指南。
还值得一提的是,我是Solid Framework的作者。因此,我不能在这里表现出任何偏见。但是我打算让这些数字在很大程度上说明自己。撇开所有这些,享受比较。
我已经采用了JS框架基准测试的最新Chrome 87 监控结果。它们在Fedora 33下的Core i7 Razor Blade 15上运行,且缓解措施已关闭。
我过滤掉了所有有问题的实现,然后获得了Github星级的前20个库。对于具有多个版本的库,我没有使用第三方库就获取了它们的最新版本和性能最高的变体。
1. Vue (177k)
2. React (161k)
3. Angular (68.9k)
4. Svelte (40.5k)
5. Preact (27.9k)
6. Ember (21.7k)
7. HyperApp(18.2k)
8. Inferno (14.6k)
9. Riot (14.4k)
10. Yew (14.2k)
11. Mithril (12.5k)
12. Alpine (12.4k)
13. Knockout (9.9k)
14. Marko (9.9k)
15. lit-html (6.9k)
16. Rax (7k)
17. Elm (6.2k)
18. Ractive (5.8k)
19. Solid (4.7k)
20. Imba (4.1k)
注意:我将把LitElement实现用作lit-html示例,因为标准示例已被标记为问题。开销应该最小,因为它是包装在单个Web组件中的原始lit-html。
这是当前Web开发生态系统中相当不错的一部分。尽管Github Stars并不是全部,但在比较中有100多个库,因此我需要标准来选择竞争者。
每个库将在3个类别中进行比较:DOM性能,启动指标和内存使用情况。此外,我将框架分为4组,以将它们与原始性能同级进行最佳比较。但是,我将在所有三个方面对库进行排名。
在每个组中,将存在参考Vanilla JavaScript条目。使用所有最佳技术,此实现都经过了最佳化以达到最佳性能。它将作为所有比较的基准。
因此,让我们开始吧。
这是最大的组,由一些最受欢迎的库组成。还有许多来自Facebook,Google,eBay和Alibaba等公司支持的公司。这些库要么在性能上较少关注某个方面,要么在某一方面强调性能,而在其他方面则受苦。
> Group 4 Performance
这里有很多红色和橙色,但请记住,这些库平均仅比我们在此处使用的痛苦手工制作的命令式Vanilla JavaScript示例慢大约2倍。400ms与200ms有何不同?
在原始性能方面,React是该包的领导者。考虑到架构的差异性,尽管它从未间断令人惊奇,但React,Marko,Angular和Ember的整体距离有多近。仍然是React,这是React Hooks的实现,在这里是领导者。对于所有指向额外的函数创建并坚持使用类的人来说,性能参数不在您身边。React Hooks是使用React的最高效的方法。
这里的大多数库要么简单的列表排序导致交换行性能确实很差,要么创建成本很高。Ember是这种情况的极端案例,因为它的更新性能比该组中的其他成员要好得多,但在某些最坏的情况下却是创建过程。
最慢的库(Knockout,Ractive和Alpine)都是具有类似架构的细粒度反应库。Knockout和Ractive(也由Svelte的作者Rich Harris撰写)来自2010年初VDOM库主导之前。我还怀疑Alpine是否期望使用其JavaScript方法来渲染1万行。在比较之后,我们将看不到另一个纯粹的细粒度反应库。
接下来,我们将主要根据库捆绑软件的大小来比较类别的启动指标。
> Group 4 Startup
此处订单变化很大。在Alpine性能最差的地方,我们可以看到它具有最小的捆绑包大小和最快的启动时间。Marko(来自eBay)紧随其后,其次是Rax(来自阿里巴巴)。所有这三个库都是为服务器端渲染而构建的,主要是通过更轻松的客户端交互来实现的。这就是为什么他们要进入第4组才能获得出色的表现,但却领先于这里的原因。
表格的后半部分是我们在基准测试中拥有的最大的捆绑软件,以Ember结尾,是任何其他实现的两倍以上。我不知道为什么要花费超过半兆字节才能呈现此表。但这确实会损害启动性能。
我们要看的最后一类是内存消耗。
> Group 4 Memory
内存往往会反映出我们已经看到的模式,因为它会对性能产生重大影响,而大型库往往会使用更多模式。Alpine,Marko和React引领潮流。老化的细粒度反应库使用最多的Ember。Ember是巨大的。仅在页面上渲染6个按钮之后,它已经使用了比Vanilla在整个套件中要使用的更多的内存。
通常,该组在GitHub上代表30万颗星,可能是NPM下载量的最大部分,但Marko和Alpine在此人群中的平均排名最高。在性能方面,React排名第三,仅次于他们。
这是我们拥有钛白粉比例框架的组,而我们的旧React库也已经消失了。让我们继续乐观一些。
在这些框架中,您可以知道已经考虑了性能。他们意识到规模,并且在创建和更新成本之间找到了平衡。我们看到了各种各样的方法。Yew中的一个Web Assembly框架(用Rust编写),LitElement中的一个Web组件。
事不宜迟,让我们看看他们的做法。
> Group 3 Performance
分数已经提高了一点,我们看到的差距甚至更大。Preact是该组中性能最高的,仅增加了LitElement。Vue 3和Riot捆绑在一起,这两个库都位于中间,它们的历史都包括反应性和VDOM。Mithril是最早将性能放在首位的VDOM库之一,Yew是唯一的WASM库尾部。
在性能方面,所有这些库都是相似的。在这堆中没有纯的反应库。它们都使用自顶向下的呈现方式,无论是VDOM还是简单的Tag Template Literal diff。与上一组相比,它们的对帐清单更智能(请参阅交换行性能)。但是,大多数仍然具有某些最慢的选择行性能。
Yew是例外,但在其他方面则较慢。让我们看看其余的测试是否有帮助。
> Group 3 Startup
情况有所改观,但在启动指标方面,Preact仍然处于领先地位。Yew是这一堆中唯一真正的大型库。WASM库的确偏大。
再次,我们看到一种结果配对。Vue是Yew最大的第二名。Preact和Riot非常紧凑。Mithril和LitElement在中间
Preact是React的4kb替代品,绝对是我们迄今为止所看到的最小的库。但是最小的库仍在继续。尽管如此,这个范围内的任何库都不应该太关注它们的包大小。
> Group 3 Memory
Yew这次赢了。在所有经过测试的框架中,它具有最小的内存占用量。WASM库在这里往往做得很好。其他都非常接近。Mithril和普瑞特Preact是最差的,但不是很多。
这里没有太多可拉的东西。您可能会认为LitElement示例可能比其他非红豆杉库更轻巧,因为它没有像其余的那样使用虚拟DOM。但是,正如我们将在以后看到的,VDOM并不意味着更多的内存。
Riot和Preact的平均排名最高,其次是LitElement,排名第三。Riot虽然没有脱颖而出,但在这个小组中没有弱点,因此取得了胜利。但是,对于这些框架中的任何一个都很难失望。借助WASM和Web组件,它们代表了许多人认为Web的未来。
但是我们还没有完成。下一组代表对网络未来的不同想法。输入编译器…
这一组是激烈的竞争。我们拥有大多数被称为编译语言的库。每个都有自己的风味。我们拥有不变的结构化Elm,受Ruby启发的Imba和"消失的" Svelte。
注意:引起我注意的是,并不是每个人都熟悉Svelte以前的"消失的框架"绰号。它描述了从输出中基本进行自我编译的能力。我不是在建议Svelte去任何地方。对带来困惑感到抱歉。
奇怪的是HyperApp,它与其他应用程序完全相反。没有编译器。没有模板。只需h函数和一个最小的Virtual DOM。
猜猜这将如何发展?
> Group 2 Performance
好吧,最小的虚拟DOM胜出。与最近的言论相反,事实证明虚拟DOM不仅是性能不佳的秘诀,而且编译并没有使其他库受益。
在已编译的库中,我们实际上看到了3种不同的方法来渲染所有具有大约相同的平均性能。Imba使用DOM协调(更接近我们之前看到的LitElement),Elm使用虚拟DOM,最后一个Svelte使用组件反应系统。
您应该注意,虚拟DOM库的选择行最差,因为这是其额外工作所显示的。但是这些库还具有更快的初始渲染。如果您仔细观察到目前为止的结果,您应该注意到Virtual DOM库与Reactive库之间的共享特性。但除此之外,性能还很严格。
因此,让我们继续。我们的编译器如何调整启动时间/捆绑大小?
> Group 2 Startup
好吧,正如您所看到的那样,这个小的虚拟DOM库不仅性能更高,而且比其他的更小。实际上,HyperApp是我们所有库中最小的实现。编译器无法赢得成功。
它和Svelte都比我们的Vanilla JavaScript参考构建小。那怎么可能?以一种更可重用的方式编写更少的代码来编写抽象。Vanilla JS实现针对性能而非大小进行了优化。
Elm在这个群体中仍处于规模竞争中。但是,Imba开始进入某些第4组库的范围。
好了,留下记忆。编译器大放异彩的最后机会。
> Group 2 Memory
内存接近,几乎是平局,但是Svelte最终为编译器赢得了胜利。对虚拟DOM的一些甜蜜的报复显示它比它更小,更快。
老实说,所有这些库都具有出色的内存配置文件。现在应该很清楚,更少的内存和更好的性能之间的关系。
不相信炒作吗?
不。更多的事情比表面上看起来复杂。精心设计的系统,无论是运行时还是编译时,或者无论采用何种技术方法,都可以制成高性能的系统。
HyperApp是该组的明显赢家,其后是Svelte,其次是Elm和Imba。通过这种对性能的专注,您知道这些库在大多数情况下都可以提供,并且始终显示在基准测试的顶部。
那还剩下什么?
如果我告诉您,声明性JavaScript库对它们的性能如此有信心,就不用担心原始WASM,Web Worker或您使用的任何技术,该怎么办。欢迎来到…
在某一时刻,它可能被称为"超快",我相信它曾经是这些库的口号之一。如果您要跟踪的话,只剩下2个库了。实际上,这类库中有少数几家不断推陈出新。但是在流行的中只有2种。它们平均比原始的手工优化Vanilla JS慢20%。
这是要看的东西。在这里,我们有2个库,如果查看它们的代码,它们可能被视为同级库,但使用的方法完全不同。Inferno是世界上性能最高的虚拟DOM库之一。在最出色的5个执行者中,有3个是虚拟DOM库。选择行测试的速度下降可以视为证据。
另一方面,Solid使用细粒度的反应性,例如第4组中最慢的旧库。重新出现此技术的位置很奇怪,但正如我们所见,Solid解决了它们的弱点。创建时间与更新时间一样快。与Vanilla JavaScript的5%差距令人难以置信。
奇怪的是,Inferno和Solid的共同点是JSX模板和React受启发的API。对于所有其他具有经过优化的自定义DSL的库,也许您不会期望在性能的顶峰找到任何东西。但是,正如HyperApp所示,某些事情对性能的影响比人们想象的要小。
> Group 1 Startup
Solid将HyperApp和Svelte作为第三个库加入,其库比Vanilla JS实现小。但是Inferno也不是懈怠。
似乎性能库较小时,有时添加更多代码可以提高性能。更好的列表协调算法,更明确的防护措施,更精细的更新。
Inferno可能比前几组中的某些库更大,但它仍然是一个10kb以下的库,并且几乎在所有性能上均不如预期。
> Group 1 Memory
在那里。除了Yew及其对WASM的使用以外,它们是整个竞争中最低的内存消耗框架。考虑到他们的表现,这并不奇怪。
这种内存消耗数字反映了对对象的非常仔细的考虑,并创建了闭包。其中很多确实来自两个库都进行的定制JSX转换。
内存性能的提高对Solid尤为重要,因为Solid与大多数细粒度的反应式库一样,都将CPU开销换成了内存消耗。在这种比较中,能够征服内存开销是Solid如何采用与大多数最慢的库类似的技术并使之成为最快的方法的很大一部分。
天空是极限。
…或者说Vanilla JavaScript是。但是我们这里的声明式库性能如此之差,您永远都不会知道它们之间的区别。当使用DOM时,我们需要认真考虑,许多不同的技术可以有效地渲染DOM。
我们在这里看到它。Solid在十年前就被认为是古老而缓慢的技术,夺得了性能冠军,而Inferno再一次证明了虚拟DOM不能高效完成的工作。
在构建JavaScript前端时,我们有很多选择。这只是快速浏览框架带来的性能开销。当涉及到应用程序中的实际性能时,用户代码具有更大的影响。
但是,我真正想在这里打动的是,测试您的解决方案并了解性能是很重要的。现实总是与营销不同。虚拟DOM不能保证很慢。不能保证编译器会产生最小的捆绑包。自定义模板DSL不能保证是最佳的。
最后,我将为您提供完整的表,将所有库一起显示。仅仅因为库快要结束了,并不一定意味着它很慢,但是与这些竞争激烈的竞争对手相比,它的得分更差。
单个图表中的所有框架。
所有结果都添加到一个列表中(第1名获得20分,最后1名获得分)。在平局的情况下,性能优先。
1. Solid (57)
2. HyperApp (54)
3. Inferno (51)
4. Svelte (51)
5. Elm (46)
6. Riot (40)
7. Preact (39)
8. Imba (36)
9. lit-html (36)
10. Yew (32)
11. Vue (29)
12. Mithril (29)
13. Marko (28)
14. Alpine (28)
15. React (19)
16. Rax (16)
17. Angular (12)
18. Knockout (11)
19. Ractive (8)
20. Ember (6)
特别提及AJ Meyghani在2018年的比较,这启发了这篇文章。
(本文由闻数起舞翻译自Ryan Carniato的文章《JavaScript Frameworks, Performance Comparison 2020》,转载请注明出处,原文链接:https://medium.com/javascript-in-plain-english/javascript-frameworks-performance-comparison-2020-cd881ac21fce)
中级
一小时
有一定编程经验。
Typescript
组件,正如它名字一样,由各个部分组合而成。它包含哪些部分呢?来看下面这张图:
图中列出了四个文件:
大家发现它们之间的共同点了吗?
下面通过问答的形式一步一步详细讲解组件。
Q:为什么这个四个文件是以app开头?是不是组件都是以app开头?
组件的基本组成部分文件命名规范是:
组件名称.component.文件类型
例如:app.component.css
组件名称:app
文件类型:css样式
中间英文单词component翻译过来是组件的意思,把它放在中间起到一个区分作用,让人一眼就知道这是组件的一部分。
整体见名知意就是负责组件样式的文件。
综上所述:组件不是都以app开头。
Q:“app.component.spec.ts”后缀和其他三个不太一样,它的文件类型是什么呢?
“app.component.spec.ts”的文件类型是ts(Typescript)。它是负责组件的单元测试功能。
它的命名规范和上面组件组成部分命名规范是不一样的。
下面是组件单元测试的命名规范:
组件名称.component.spec.文件类型
Q:这四个文件它们的作用分别是什么?
app.component.css:负责组件样式。
app.component.html:负责组件模版。
app.component.spec.ts:负责组件单元测试。
app.component.ts:负责组件逻辑。
Q:组件的基本组成部分只有这四个吗?
对的,其中只有单元测试不是必须的。也就是“app.component.spec.ts”文件可以不要。
好了,有关组件的组成部分就介绍到这。
下面进入今天的主题内容,负责组件逻辑的“app.component.ts”。
“app.component.ts”位置及内容:
具体内容:
我们要分三部分来看组件中的内容:
第一部分,导出的组件类:
第二部分,@Component装饰器:
第三部分,组件类中的属性:
从图中我们可以看到,这是一个普通的类。其实,组件类就是一个普通的类。
书写一个组件类时,它的类名首字母必须是大写,同时得遵循骆驼命名法。
它的名称是怎么来取的呢?
注意看它的文件名“app.component.ts”,最后的文件类型去除后,将其“app”和
“component”前后部分,按照首字母大写和骆驼命名法规则书写,书写的结果就是“AppComponent”。
这一部分也称之为“组件的元数据”。
我们先来看官方的描述:
@Component 装饰器会指出紧随其后的那个类是个组件类,并为其指定元数据。 在下面的范例代码中,你可以看到 AppComponent 只是一个普通类,完全没有 Angular 特有的标记或语法。 直到给它加上了 @Component 装饰器,它才变成了组件。
组件的元数据告诉 Angular 到哪里获取它需要的主要构造块,以创建和展示这个组件及其视图。 具体来说,它把一个模板(无论是直接内联在代码中还是引用的外部文件)和该组件关联起来。 该组件及其模板,共同描述了一个视图。
除了包含或指向模板之外,@Component 的元数据还会配置要如何在 HTML 中引用该组件,以及该组件需要哪些服务等等。
这个例子展示了一些最常用的 @Component 配置选项:
提示:文件地址中的“.”表示当前路径。
将他们的值结合解释就是:
selector的值为“app-root”,在需要显示App组件的HTML中写上<app-root></app-root>即可。
templateUrl的值为“./app.component.html”,而“app.component.html”我们知道,它和“app.component.ts”都在app目录下,作用就是组件的模版,里面写的都是HTML代码。
“app.component.html”内容:
这个就是组件呈现的模版内容,为什么说是模版内容呢?
因为里面还涉及到占位符(即不是实际数据,暂时用其他名称代替)。比如下面即将要说到的title。
styleUrls的值为“['./app.component.css']”,注意,它比“./app.component.html”多了一个中括号,在编程语言中,我们都用 [](中括号)来表示数组,它可以有多个类型一样的值。这里的 [](中括号)表示的也是这个意思,表示可以有多个像“./app.component.css”一样的组件样式,其中“./app.component.css”里面写的都是CSS代码。同样,“app.component.css”和“app.component.html”还有“app.component.ts”都在app同一目录下。
“app.component.css”内容没有写东西,暂时是空的。
如图所示,AppComponent组件类中有一个title属性,值为“hello”。
在第二部分的“app.component.html”内容中,我们看到这样一段代码:
其中被<h1>标签中的内容“Welcome to {{ title }}!”,出现了title字样,还被 {{ }} (两个花括号)包裹着,它们之间有关联吗?先打一个问号,接着,来证明他们之间是有关联的。
运行Angular应用,主页面显示如下:
大家看到了什么?“Welcome to hello!”
这说明了,“app.component.ts”组件类里的属性绑定到了“app.component.html”模版中,然后经过Angular CLI编译,浏览器进行渲染成最终的页面。
那么有人就要问了,“app.component.html”模版中为什么要用 {{ }} (两个花括号)把title包裹起来呢?
{{ }} 叫插值表达式。可以将组件类里的属性绑定到组件模版中。后面章节中会详细讲解。
在“app.component.ts”定义一个subTitle属性,值为“Angular”,然后将其绑定到“app.component.html”组件模版中,位置在“Welcome to hello!”的下面,被<h1>包裹,内容最终为“I like Angular”。
示例:
“app.component.ts”组件类:
“app.component.html”组件模版:
最终页面:
看看你的是否跟我一样呢?
我们大家一起回顾之前主页面“index.html”那一章,在那一章我们知道“index.html”是用户第一个访问到的页面,内容如下:
其中我们看到了在<body>标签里面有一个<app-root>标签:
我们说过,这个<app-root>标签是AppComponent组件。
这还不算是重点,重点是大家有没有发现<body>标签里面就一个<app-root>标签,其他什么都没有。但是启动Angular应用之后竟然是这样的页面:
每个 Angular 应用都至少有一个组件,也就是根组件,它会把组件树和页面中的 DOM 连接起来。 每个组件都会定义一个类,其中包含应用的数据和逻辑,并与一个 HTML 模板相关联,该模板定义了一个供目标环境下显示的视图。
上述是官方对根组件对描述。
由此看来,AppComponent就是应用的根组件,以后再有新的组件出来,它们的父组件大多数会是AppComponent,它们的selector也会写在“app.component.html”组件模版中。
至此,Angular组件已有一个初步了解,更深入的了解在后续开发中再讲解。
如果大家有问题或想了解更多前沿技术,请在下方留言或评论,我会为大家解答。
Angular第二十章:app开发目录
Angular第二十二章:组件的HTML模版
加入同步学习小组,共同交流与进步。
如果你也热爱前沿技术,欢迎关注我们。
原创不易,未经允许不得转载!
*请认真填写需求信息,我们会在24小时内与您取得联系。