React i Vue to narzędzia JavaScript do budowania interfejsów użytkownika z komponentów (React nazywa siebie biblioteką, Vue progresywnym frameworkiem) i dzielą większość pomysłów: propsy w dół, zdarzenia w górę, reaktywny stan, wirtualny DOM. Praktyczne różnice polegają na tym, że React zapisuje znaczniki w JSX i oczekuje, że stan zostanie zastąpiony przez setter, a Vue zapisuje znaczniki w szablonach HTML wewnątrz komponentów jednoplikowych i pozwala zmieniać reaktywne wartości bezpośrednio. Oto licznik w React:
I ten sam licznik jako komponent jednoplikowy Vue (Counter.vue):
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
<template>
<button @click="count++">Clicked {{ count }} times</button>
</template>
useState(0) staje się ref(0), onClick staje się @click, a {count} staje się {{ count }}. Widoczna różnica to count++: Vue pozwala zmienić wartość w miejscu, a jego system reaktywności to zauważa. React potrzebuje setCount, bo renderuje ponownie tylko wtedy, gdy dostanie nową wartość.
JSX a komponenty jednoplikowe
Komponent Reacta to funkcja JavaScript, która zwraca JSX. Warunki to && albo operator warunkowy, listy to .map(), a style pochodzą z tego, co wybierzesz (pliki CSS, CSS modules, framework klas narzędziowych).
Komponent Vue to zwykle plik .vue z trzema blokami: <script setup> na logikę, <template> na znaczniki i opcjonalny <style scoped>, którego CSS dotyczy tylko tego komponentu. Szablony używają dyrektyw: v-if, v-for, v-model do dwukierunkowego wiązania pól, :prop do wiązania wartości i @event do nasłuchiwania. Szablony utrzymują znaczniki czytelne dla każdego, kto zna HTML; JSX daje w znacznikach cały JavaScript. Vue też może używać JSX, a React nie może używać szablonów, ale większość kodu w każdym z nich trzyma się wartości domyślnej.
Oto przefiltrowana lista, druga funkcja do porównania.
Spróbuj wpisać xyz, żeby zobaczyć komunikat o pustej liście, a potem to usuń. Wersja w Vue:
<script setup>
import { ref, computed } from 'vue';
const fruits = ['Apple', 'Banana', 'Cherry', 'Grape', 'Mango', 'Peach'];
const query = ref('');
const visible = computed(() =>
fruits.filter((f) => f.toLowerCase().includes(query.value.toLowerCase()))
);
</script>
<template>
<input v-model="query" placeholder="Filter fruit" />
<ul>
<li v-for="fruit in visible" :key="fruit">{{ fruit }}</li>
<li v-if="visible.length === 0">No match</li>
</ul>
</template>
v-model zastępuje parę value i onChange, a computed zastępuje zwykłą zmienną. W React visible jest wyliczane przy każdym renderowaniu, bo funkcja komponentu wykonuje się ponownie; w Vue computed zapamiętuje wynik i przelicza go tylko wtedy, gdy zmienia się query. Oba używają key do odróżniania elementów listy.
Model reaktywności
To najgłębsza różnica między nimi.
React: niemutowalny stan i ponowne renderowanie. Stan to migawka. Wywołujesz setter z nową wartością, React ponownie wykonuje funkcję komponentu, porównuje nowy JSX ze starym i aktualizuje DOM. React porównuje wartości przez Object.is, więc zmiana obiektu albo tablicy w miejscu i przekazanie z powrotem tego samego wygląda tak, jakby nic się nie zmieniło.
Kliknij "push() in place", a na ekranie nic się nie zmieni, bo tablica to ten sam obiekt. Potem kliknij "New array": renderowanie pokazuje też pushed, bo wcześniejsza mutacja naprawdę się wydarzyła, React po prostu nie miał powodu, żeby spojrzeć. Strona o useState dokładnie omawia ten wzorzec.
Vue: mutowalne reaktywne wartości. ref albo obiekt reactive zapisuje, kto go czyta (ref przez getter .value, obiekt reactive przez proxy). Gdy do niego zapisujesz, Vue wie dokładnie, które wartości computed, obserwatory (watchers) i części szablonu od niego zależą, i aktualizuje tylko je. W Vue items.value.push('pushed') aktualizuje ekran. Piszesz mniej ceremonii, a rezygnujesz z gwarancji, że wartość nigdy nie zmieni się bez twojej wiedzy.
Żaden model nie jest szybszy w sposób, który miałby znaczenie w typowych aplikacjach. React może wykonywać więcej kodu komponentów na zmianę i polega na memoizacji (ręcznej albo przez React Compiler), żeby pomijać pracę; Vue śledzi zależności w czasie działania, więc domyślnie tę pracę pomija.
Composition API a hooki
Composition API z Vue 3 i hooki Reacta rozwiązują ten sam problem: umieszczenie powiązanego stanu i logiki razem i ponowne ich użycie w wielu komponentach. Vue nazywa funkcje wielokrotnego użytku composables (useMouse()), React nazywa je własnymi hookami (useMouse()). Zasady różnią się z powodu momentu wykonania kodu.
- Kiedy się wykonuje.
setupw Vue wykonuje się raz, gdy komponent jest tworzony. Funkcja komponentu Reacta wykonuje się przy każdym renderowaniu, a hooki w jej środku razem z nią. - Zasady kolejności. React dopasowuje hooki po kolejności wywołań, więc nie możesz wywoływać ich w warunkach ani pętlach. Vue nie ma takiej zasady dla
reficomputed, bo setup wykonuje się raz. - Zależności. Efekty i memo w React wymieniają zależności w tablicy, którą utrzymujesz sam.
watchEffecticomputedw Vue automatycznie śledzą to, co czytają. - Nieaktualne wartości. Callback w React może przechwycić starą wartość stanu z wcześniejszego renderowania (klasyczny błąd z
setInterval). Callback w Vue czytacount.valuew chwili wywołania i zawsze widzi bieżącą wartość.
Model Reacta sprawia, że każde renderowanie to czysta funkcja propsów i stanu, co łatwo testować i analizować. Model Vue usuwa całą klasę błędów związanych z tablicami zależności. Programiści, którzy znają jedno, zwykle szybko łapią drugie.
Ekosystem
| React | Vue | |
|---|---|---|
| Znaczniki | JSX | Szablony HTML w plikach .vue (JSX opcjonalnie) |
| Aktualizacje stanu | Zastąpienie przez setter, potem ponowne renderowanie | Zmiana reaktywnej wartości, zależne części się aktualizują |
| Ponowne użycie logiki | Własne hooki | Composables |
| Wartości pochodne | Wyliczane podczas renderowania, useMemo | computed (zapamiętane) |
| Dwukierunkowe wiązanie pól | value plus onChange | v-model |
| CSS o ograniczonym zasięgu | Brak wbudowanego (CSS modules, biblioteki) | Wbudowane <style scoped> |
| Routing | React Router, TanStack Router, frameworki | Vue Router (oficjalny) |
| Stan globalny | Kontekst, Zustand, Redux Toolkit | Pinia (oficjalna) |
| Framework full-stack | Next.js, React Router w trybie frameworka | Nuxt |
| Aplikacje mobilne | React Native | Brak oficjalnej opcji (Capacitor, NativeScript-Vue) |
| Narzędzie do budowania | Vite albo framework | Vite |
| Kto utrzymuje | Meta i społeczność | Niezależny zespół główny i społeczność |
Wzorzec w tej tabeli: zespół główny Vue utrzymuje razem router, magazyn danych i devtools, więc projekt w Vue ma oczywistą wartość domyślną dla każdego z nich. React zostawia je społeczności, co daje więcej opcji i więcej decyzji. Vite, zwykłe narzędzie do budowania nowych projektów w obu, zapoczątkował twórca Vue.
Krzywa nauki
Vue często daje łagodniejszy start. Szablony czyta się jak HTML, który już znasz, v-model usuwa szablonowy kod kontrolowanych pól, a reaktywna wartość aktualizuje ekran, gdy ją zmienisz. React od razu wymaga JSX i nawyku niemutowalnych aktualizacji, a strona o JSX to pierwsza rzecz, której potrzebuje większość osób.
Po podstawach różnica się zmniejsza. Vue dodaje własne pojęcia (refy a obiekty reactive, .value w skryptach, ale nie w szablonach, obserwatory), a React dodaje efekty, memoizację i zasady hooków. Oferty pracy w twojej okolicy to bardziej użyteczne kryterium rozstrzygające niż składnia.
Kiedy co wybrać
Wybierz React, gdy:
- Chcesz szerokiego wyboru bibliotek i komponentów społeczności albo planujesz budować natywne aplikacje mobilne w React Native.
- Lubisz trzymać logikę i znaczniki w jednej funkcji JavaScript i chcesz frameworka takiego jak Next.js.
- Twój zespół ceni jawne, niemutowalne aktualizacje, dzięki którym łatwo prześledzić każde renderowanie.
Wybierz Vue, gdy:
- Chcesz oficjalnych, dopasowanych do siebie narzędzi do routingu i stanu i mniej decyzji do podjęcia.
- W twoim zespole są projektanci albo programiści backendu, którzy dobrze czują się w szablonach HTML.
- Dodajesz interaktywność do istniejących stron renderowanych na serwerze: Vue można wrzucić na stronę przez tag script i stopniowo rozbudowywać.
Oba są dojrzałe i używane na produkcji przez firmy każdej wielkości, a pojęcia, których nauczysz się w jednym (komponenty, propsy, stan pochodny, listy z kluczami), przenoszą się bezpośrednio do drugiego.
Najczęściej zadawane pytania
Czy Vue jest łatwiejsze niż React?
Wielu początkujących uważa, że na początku Vue jest łatwiejsze, bo szablony wyglądają jak zwykły HTML, a zmiana reaktywnej wartości (count.value++) aktualizuje ekran bez settera. React wymaga nauki JSX i zasady, że stan trzeba zastąpić, a nie zmienić. Po pierwszych tygodniach trudność jest podobna.
Co jest lepsze, React czy Vue?
Ogólnie żadne nie wygrywa. React zostawia routing i stan bibliotekom społeczności i ma React Native do aplikacji mobilnych. Vue ma oficjalny router, magazyn danych i devtools utrzymywane razem oraz szablony, które wielu osobom łatwiej się czyta. Wybierz to, czego używa twój zespół albo rynek pracy.
Czym różni się Composition API z Vue od hooków Reacta?
Oba grupują logikę ze stanem w funkcje wielokrotnego użytku. setup w Vue wykonuje się raz na komponent i automatycznie śledzi zależności, więc nie ma tablic zależności ani nieaktualnych domknięć. Funkcja komponentu Reacta wykonuje się przy każdym renderowaniu, więc hooki muszą być wywoływane za każdym razem w tej samej kolejności, a efekty wymieniają swoje zależności.
Czy Vue używa JSX?
Vue obsługuje JSX przez wtyczkę, ale większość kodu w Vue używa szablonów HTML w komponentach jednoplikowych (pliki .vue). React używa JSX prawie wszędzie.
Jaki jest odpowiednik Next.js w Vue?
Nuxt. Tak jak Next.js dla Reacta, dodaje na wierzchu Vue routing oparty na plikach, renderowanie na serwerze, generowanie statyczne i trasy serwerowe.