英文: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 的哲學!