译文 | Vue 在哪些方面做的比 React 更好?
大家好,我是若川。
在過(guò)去的五年中,我一直是一名?React?工程師。我愛(ài)React。我喜歡開(kāi)發(fā)?React?應(yīng)用程序。我認(rèn)為它是目前最好的UI框架之一。
但是,在這個(gè)領(lǐng)域有一些競(jìng)爭(zhēng)對(duì)手。其中最大的是?Vue.js?。
我以前玩過(guò)一些?Vue.js,但我認(rèn)為它已經(jīng)過(guò)時(shí)了,因?yàn)槲乙钊胙芯?Vue.js?的工作原理,以及它如何讓我的工作更簡(jiǎn)單。
在深入研究?Vue.js?文檔并使用?Vue.js?之后(注意:我不是?Vue.js?專(zhuān)家),在有些方面?Vue.js?比?React?做的更好。
最終我希望?React?受到?Vue.js?所做的這些事情的啟發(fā),并且也開(kāi)始這樣做。
不同的理念
Vue.js?和?React?之間的主要區(qū)別之一是它們?nèi)绾畏Q(chēng)呼自己。
React?把自己描述為 “一個(gè)用于構(gòu)建用戶(hù)界面的JavaScript庫(kù)”,而?Vue.js?則把自己描述為“漸進(jìn)式JavaScript框架”
React?是一個(gè)庫(kù),Vue.js?是一個(gè)框架。我認(rèn)為這是在很多方面他們處理方式不同的原因。
從歷史上看,框架在提供和要求方面更全面、更詳盡,而庫(kù)則更簡(jiǎn)潔、功能更少,但它們所專(zhuān)注的事情卻做得非常好。
單個(gè)組件
Vue.js?和?React?都具有作為創(chuàng)建UI的構(gòu)件的組件。
組件通常由3部分組成:
界面(HTML)
行為(JavaScript)
外觀(guān)(CSS)
Vue.js?的概念是?Single File Component?是一種開(kāi)箱即用的方式來(lái)編寫(xiě)涵蓋所有3個(gè)部分的組件。
<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?工程師就能理解這里發(fā)生了什么。
React?組件提供了開(kāi)箱即用的?UI?和?Behavior,但是樣式在很大程度上不受限制:
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>); }當(dāng)然,React?有一個(gè)非常豐富的社區(qū),因此如果你想包含樣式,可以輕松獲取?Emotion?或?Styled Components?,它們將填補(bǔ)?Style?的空缺,但是:
它不是內(nèi)置的
你必須知道這些庫(kù)存在才能使用它們。
官方支持的相關(guān)庫(kù)
任何足夠大且復(fù)雜的UI應(yīng)用程序都需要兩個(gè)附加功能來(lái)支持它們的實(shí)現(xiàn):
路由
狀態(tài)管理
Vue.js?官方支持的庫(kù)分別覆蓋了這兩種用例,Vue Router和?Vuex。
這些庫(kù)在?Vue.js?文檔頁(yè)面中明確提到,它們是在?Vue.js?核心中開(kāi)發(fā)和維護(hù)的。
它為新的?Vue.js?工程師提供了解決問(wèn)題的清晰方法,并使他們相信這些庫(kù)可以持久使用。
擁有第一方支持的庫(kù)并不限制社區(qū)解決方案,但確實(shí)為新用戶(hù)提供了入門(mén)解決方案。
風(fēng)格指南
嗯,我非常希望?React?也有這個(gè),Vue.js?的風(fēng)格指南?https://v3.vuejs.org/style-guide/?回答了新手可能遇到的許多問(wèn)題。它提供了有關(guān)如何編寫(xiě)?適當(dāng)?shù)?和?易于訪(fǎng)問(wèn)的?Vue.js?應(yīng)用程序的最佳實(shí)踐和指南。
它共享了經(jīng)過(guò)實(shí)戰(zhàn)使用的經(jīng)驗(yàn),以及社區(qū)中的最佳實(shí)踐和模式。
最重要的是:它是由?Vue.js?本身維護(hù)和支持的!
類(lèi)和樣式綁定
如上所述,Vue.js?內(nèi)置了對(duì)樣式的支持。此外,Vue.js?本質(zhì)上是內(nèi)置庫(kù)類(lèi)名的。
Classnmes?是一個(gè)很棒的庫(kù),可以方便地連接和動(dòng)態(tài)構(gòu)造應(yīng)用于HTML元素的CSS類(lèi)名。
在?React?中,你必須知道這個(gè)庫(kù)的存在,然后安裝它。
在?Vue.js?中,這只是另一個(gè)內(nèi)置特性。
<divclass="static":class="{?active:?isActive,?'text-danger':?hasError?}" ></div>像這樣的數(shù)據(jù):
data()?{return?{isActive:?true,hasError:?false} }最終的用戶(hù)界面將是:
<div?class="static?active"></div>內(nèi)置此功能真棒。
Vue.js?進(jìn)一步支持內(nèi)聯(lián)樣式。Vue.js?和?React?一樣,都支持內(nèi)聯(lián)樣式,但是?Vue.js?超越?React?的地方是它能夠自動(dòng)為需要的?CSS?加上前綴。
來(lái)自文檔:
當(dāng) v-bind:style 使用需要添加瀏覽器引擎前綴的 CSS property 時(shí),如 transform,Vue.js 會(huì)自動(dòng)偵測(cè)并添加相應(yīng)的前綴。
插槽
React?中的一切都是?prop。
如果要在?React?組件中渲染多個(gè)子代,則只需添加更多?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>); }效果很好,但是有點(diǎn)尷尬,尤其是當(dāng)?prop?內(nèi)部的內(nèi)容變大時(shí)。
Vue.js?通過(guò)?Slots?采用了不同的方法,我認(rèn)為它的?API?更加簡(jiǎn)潔。
<!--?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?使用?Slots?清楚地指示內(nèi)容在組件內(nèi)部的位置。
Vue.js?反復(fù)執(zhí)行的操作為常見(jiàn)任務(wù)提供了捷徑。在這種情況下,可以使用?Slot?來(lái)簡(jiǎn)化上面的示例:
<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?具有稱(chēng)為“指令修飾符”的功能,我認(rèn)為它真的很酷。
在我談?wù)撝噶钚揎椃?#xff0c;讓我快速介紹一下指令是什么。
指令?v-?是你在?Vue.js?模板中使用的“帶有前綴的特殊屬性”。
指令的工作是在其表達(dá)式的值發(fā)生變化時(shí)以反應(yīng)方式將副作用施加到DOM
例如:
//?If?"seen"?variable?is?false?then?this?p?tag?is?not?rendered <p?v-if="seen">Now?you?see?me</p>有針對(duì)事件處理程序的指令:
<!--?full?syntax?--> <a?v-on:click="doSomething">?...?</a><!--?shorthand?--> <a?@click="doSomething">?...?</a>指令還支持修飾符。
這是使用通用指令執(zhí)行通用任務(wù)的非常友好的開(kāi)發(fā)人員方式。
對(duì)于事件處理程序指令(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?中執(zhí)行這樣的操作,可以創(chuàng)建一個(gè)輔助函數(shù)或一個(gè)自定義組件。但與指令修飾符相比并不簡(jiǎn)潔。
我很好奇是否有人可以開(kāi)發(fā)一個(gè)?Babel JSX?超集,然后可以編寫(xiě)如下代碼:
<form?onSubmit.prevent={onSubmit}?/>它將轉(zhuǎn)換為:
React.createElement(form,?{?onSubmit:?preventWrapper(onSubmit)?});這不在?React?的精神范圍內(nèi),但我仍然認(rèn)為這是一次超級(jí)簡(jiǎn)潔的生產(chǎn)效率提升。
還有更多的?Vue.js?修飾符。最酷的一些是關(guān)鍵修飾符:
<!--?only?call?`submit()`?when?the?`key`?is?`Enter`?--> <input?@keyup.enter="submit"?/><input?@keyup.page-down="onPageDown"?/>非常非常酷
表單輸入綁定
當(dāng)將數(shù)據(jù)綁定到輸入元素時(shí),v-model?指令有一個(gè)非常有趣的特性。
從文檔中發(fā)現(xiàn),v-model?內(nèi)部使用了不同的屬性,并為不同的輸入元素發(fā)出了不同的事件:
text?和?textarea?元素使用?value?屬性和?input?事件;
復(fù)選框和單選按鈕使用?checked?屬性和?change?事件;
select?使用?value?用作屬性和?change事件。
這樣做的好處是,你不需要關(guān)心數(shù)據(jù)是如何同步的,你只需要關(guān)心它是如何為你服務(wù)的。
讓我們比較一下?React?將如何進(jìn)行這些綁定以及?Vue.js?如何進(jìn)行綁定:
//?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>現(xiàn)在,我要為 React 辯護(hù)的一點(diǎn)是,React 鼓勵(lì)你學(xué)習(xí)數(shù)據(jù)實(shí)際上是如何設(shè)置的以及它是如何變化的。這意味著,如果你曾經(jīng)用普通JS寫(xiě)過(guò)一個(gè)表單,你將有更多關(guān)于它如何工作的知識(shí),并能夠正確地編碼它。與Vue.js不同,Vue.js只是將所有用法抽象出來(lái)。
自定義指令
像任何好的框架一樣,你可以在?Vue.js?中創(chuàng)建自己的自定義指令。
Vue.js?確實(shí)注意到“代碼重用和抽象的主要形式是組件”,但是為什么自定義指令可能會(huì)更好的最好的例子之一是它們的自定義?v-focus?指令自動(dòng)將輸入元素放在?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?elementel.focus()} })<input?v-focus?/>在?React?中,你可能會(huì)編寫(xiě)一個(gè)自定義組件來(lái)完成相同的事情,對(duì)于這么輕便的任務(wù)而言,這似乎有點(diǎn)繁重。
用 TypeScript 編寫(xiě)
最后但并非最不重要的一點(diǎn)是,最近在?TypeScript?中徹底重寫(xiě)了?Vue.js?。
這意味著它們的?TypeScript?支持是一流的,因?yàn)榭蚣鼙旧硎怯?TypeScript?編寫(xiě)的。
最終,React?用什么編寫(xiě)并不重要,我也不認(rèn)為它有什么太大的區(qū)別,但看到?Vue.js?所擁有的仍然是一個(gè)很不錯(cuò)的小事情。
總結(jié)
我要放棄?React?并開(kāi)始專(zhuān)門(mén)使用?Vue.js?嗎?不。我仍然非常喜歡?React?,坦率地說(shuō),我已經(jīng)非常精通編寫(xiě)?React?應(yīng)用程序。
但是,我很希望看到?React?從?Vue.js?中汲取一些靈感,并將其中一些很棒的想法整合到?React?中。如果我只能從文中提到的幾個(gè)點(diǎn)中選擇一個(gè),那絕對(duì)是?風(fēng)格指南。我很樂(lè)意看到?React?有一個(gè)官方支持和維護(hù)的風(fēng)格指南。
希望我能讓你看到一些你不知道 Vue.js 做過(guò)的事情!我很驚訝地發(fā)現(xiàn)自己真的很喜歡 Vue.js 工作的方式!
本文授權(quán)譯自:https://hswolff.com/blog/what-vuejs-does-better-than-react/
最近組建了一個(gè)江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進(jìn)群。
推薦閱讀
我在阿里招前端,該怎么幫你(可進(jìn)面試群)
畢業(yè)年限不長(zhǎng)的前端焦慮和突破方法
前端搶飯碗系列之Vue項(xiàng)目如何做單元測(cè)試
老姚淺談:怎么學(xué)JavaScript?
·················?若川簡(jiǎn)介?·················
你好,我是若川,畢業(yè)于江西高校。現(xiàn)在是一名前端開(kāi)發(fā)“工程師”。寫(xiě)有《學(xué)習(xí)源碼整體架構(gòu)系列》多篇,在知乎、掘金收獲超百萬(wàn)閱讀。
從2014年起,每年都會(huì)寫(xiě)一篇年度總結(jié),已經(jīng)寫(xiě)了7篇,點(diǎn)擊查看年度總結(jié)。
同時(shí),活躍在知乎@若川,掘金@若川。致力于分享前端開(kāi)發(fā)經(jīng)驗(yàn),愿景:幫助5年內(nèi)前端人走向前列。
總結(jié)
以上是生活随笔為你收集整理的译文 | Vue 在哪些方面做的比 React 更好?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AIR 文件系统概要
- 下一篇: 尤大是如何发布vuejs的,学完可以应用