Vue 在哪些方面做的比 React 更好?

大家好,我是若川

在過去的五年中,我一直是一名 React 工程師。我愛 React。我喜歡開發 React 應用程序。我認爲它是目前最好的 UI 框架之一。

但是,在這個領域有一些競爭對手。其中最大的是 Vue.js 。

我以前玩過一些 Vue.js,但我認爲它已經過時了,因爲我要深入研究 Vue.js 的工作原理,以及它如何讓我的工作更簡單。

在深入研究 Vue.js 文檔並使用 Vue.js 之後(注意:我不是 Vue.js 專家),在有些方面 Vue.js 比 React 做的更好。

最終我希望 React 受到 Vue.js 所做的這些事情的啓發,並且也開始這樣做。

不同的理念

Vue.js 和 React 之間的主要區別之一是它們如何稱呼自己。

React 把自己描述爲 “一個用於構建用戶界面的 JavaScript 庫”,而 Vue.js 則把自己描述爲 “漸進式 JavaScript 框架”

React 是一個庫,Vue.js 是一個框架。我認爲這是在很多方面他們處理方式不同的原因。

從歷史上看,框架在提供和要求方面更全面、更詳盡,而庫則更簡潔、功能更少,但它們所專注的事情卻做得非常好。

單個組件

Vue.js 和 React 都具有作爲創建 UI 的構件的組件。

組件通常由 3 部分組成:

Vue.js 的概念是 Single File Component 是一種開箱即用的方式來編寫涵蓋所有 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 和 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>
  );
}

當然,React 有一個非常豐富的社區,因此如果你想包含樣式,可以輕鬆獲取 Emotion 或 Styled Components ,它們將填補 Style 的空缺,但是:

官方支持的相關庫

任何足夠大且複雜的 UI 應用程序都需要兩個附加功能來支持它們的實現:

Vue.js 官方支持的庫分別覆蓋了這兩種用例,Vue Router和 Vuex

這些庫在 Vue.js 文檔頁面中明確提到,它們是在 Vue.js 核心中開發和維護的。

它爲新的 Vue.js 工程師提供瞭解決問題的清晰方法,並使他們相信這些庫可以持久使用。

擁有第一方支持的庫並不限制社區解決方案,但確實爲新用戶提供了入門解決方案。

風格指南

嗯,我非常希望 React 也有這個,Vue.js 的風格指南 https://v3.vuejs.org/style-guide/ 回答了新手可能遇到的許多問題。它提供了有關如何編寫 適當的 和 易於訪問的 Vue.js 應用程序的最佳實踐和指南。

它共享了經過實戰使用的經驗,以及社區中的最佳實踐和模式。

最重要的是:它是由 Vue.js 本身維護和支持的!

類和樣式綁定

如上所述,Vue.js 內置了對樣式的支持。此外,Vue.js 本質上是內置庫類名的。

Classnmes 是一個很棒的庫,可以方便地連接和動態構造應用於 HTML 元素的 CSS 類名。

在 React 中,你必須知道這個庫的存在,然後安裝它。

在 Vue.js 中,這只是另一個內置特性。

<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>

像這樣的數據:

data() {
  return {
    isActive: true,
    hasError: false
  }
}

最終的用戶界面將是:

<div class="static active"></div>

內置此功能真棒。

Vue.js 進一步支持內聯樣式。Vue.js 和 React 一樣,都支持內聯樣式,但是 Vue.js 超越 React 的地方是它能夠自動爲需要的 CSS 加上前綴。

來自文檔:

當 v-bind:style 使用需要添加瀏覽器引擎前綴的 CSS property 時,如 transform,Vue.js 會自動偵測並添加相應的前綴。

插槽

React 中的一切都是 prop

如果要在 React 組件中渲染多個子代,則只需添加更多 prop

function Nav({ left, right }) {
  return (
    <nav>
      <div class>{left}</div>
      <div class>{right}</div>
    </nav>
  );
}

function App() {
  return (
    <main>
      <Nav left={<Logo />} right={<UserDropdown />} />
    </main>
  );
}

效果很好,但是有點尷尬,尤其是當 prop 內部的內容變大時。

Vue.js 通過 Slots 採用了不同的方法,我認爲它的 API 更加簡潔。

<!-- A Vue.js component template named "base-layout" -->
<div class="container">
  <header>
    <slot ></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot ></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 清楚地指示內容在組件內部的位置。

Vue.js 反覆執行的操作爲常見任務提供了捷徑。在這種情況下,可以使用 Slot 來簡化上面的示例:

<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 內部使用了不同的屬性,併爲不同的輸入元素髮出了不同的事件:

這樣做的好處是,你不需要關心數據是如何同步的,你只需要關心它是如何爲你服務的。

讓我們比較一下 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 中創建自己的自定義指令。

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 編寫

最後但並非最不重要的一點是,最近在 TypeScript 中徹底重寫了 Vue.js 。

這意味着它們的 TypeScript 支持是一流的,因爲框架本身是用 TypeScript 編寫的。

最終,React 用什麼編寫並不重要,我也不認爲它有什麼太大的區別,但看到 Vue.js 所擁有的仍然是一個很不錯的小事情。

總結

我要放棄 React 並開始專門使用 Vue.js 嗎?不。我仍然非常喜歡 React ,坦率地說,我已經非常精通編寫 React 應用程序。

但是,我很希望看到 React 從 Vue.js 中汲取一些靈感,並將其中一些很棒的想法整合到 React 中。如果我只能從文中提到的幾個點中選擇一個,那絕對是 風格指南。我很樂意看到 React 有一個官方支持和維護的風格指南。

希望我能讓你看到一些你不知道 Vue.js 做過的事情! 我很驚訝地發現自己真的很喜歡 Vue.js 工作的方式!

本文授權譯自:https://hswolff.com/blog/what-vuejs-does-better-than-react/

················· 若川簡介 ·················

你好,我是若川,畢業於江西高校。現在是一名前端開發 “工程師”。寫有《學習源碼整體架構系列》多篇,在知乎、掘金收穫超百萬閱讀。
從 2014 年起,每年都會寫一篇年度總結,已經寫了 7 篇,點擊查看年度總結
同時,活躍在知乎 @若川,掘金 @若川。致力於分享前端開發經驗,願景:幫助 5 年內前端人走向前列。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/8Mlgo4VkbltVJvqjMz_nbg