Шаблоны vs JSX
Два подхода к разметке
Vue: HTML-шаблоны с директивами. React: JSX — JavaScript с разметкой.
Vue шаблон
<template>
<div class="card">
<h1 v-if="showTitle">{{ title }}</h1>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
<button @click="handleClick">Клик</button>
</div>
</template>
Директивы — как атрибуты.
React JSX
return (
<div className="card">
{showTitle && <h1>{title}</h1>}
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
<button onClick={handleClick}>Клик</button>
</div>
);
Логика — через JS-выражения.
Условия
Vue:
<p v-if="show">Текст</p>
<p v-else-if="loading">Загрузка</p>
<p v-else>Скрыто</p>
React:
{show ? <p>Текст</p> : loading ? <p>Загрузка</p> : <p>Скрыто</p>}
Vue читается проще.
Циклы
Vue:
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
React:
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
События
Vue:
<button @click="handleClick">Клик</button>
<button @click.stop="handleClick">Клик</button>
<form @submit.prevent="submit">
React:
<button onClick={handleClick}>Клик</button>
<button onClick={e => { e.stopPropagation(); handleClick(); }}>Клик</button>
<form onSubmit={e => { e.preventDefault(); submit(); }}>
Vue модификаторы — короткие.
Двусторонняя привязка
Vue:
<input v-model="name">
React:
<input
value={name}
onChange={e => setName(e.target.value)}
/>
Vue — одна строка. React — 3.
Классы
Vue:
<div :class="{ active: isActive, disabled: !isEnabled }">
React:
<div className={clsx({ active: isActive, disabled: !isEnabled })}>
React — библиотека clsx или шаблонные строки.
Стили
Vue:
<div :style="{ color: 'red', fontSize: '16px' }">
React:
<div style={{ color: 'red', fontSize: '16px' }}>
Почти одинаково.
Компоненты
Vue — PascalCase и kebab:
<UserCard />
<user-card />
React — PascalCase:
<UserCard />
Слоты vs Children
Vue:
<template>
<Card>
<template #header>Заголовок</template>
Основной контент
</Card>
</template>
React:
<Card
header={<h1>Заголовок</h1>}
>
Основной контент
</Card>
React — пропсы. Vue — слоты.
Фрагменты
Vue:
<template>
<h1>Заголовок</h1>
<p>Текст</p>
</template>
React:
<>
<h1>Заголовок</h1>
<p>Текст</p>
</>
React — <>...</>. Vue — <template>.
Опасный HTML
Vue:
<div v-html="content"></div>
React:
<div dangerouslySetInnerHTML={{ __html: content }} />
React — длиннее, но честнее — подчёркивает риск.
Функции-помощники
Vue:
@click="handleClick(arg)"
@click="count++"
React:
onClick={() => handleClick(arg)}
onClick={() => setCount(count + 1)}
React — стрелочная функция. Vue — выражение или вызов.
Что лучше
Vue шаблоны:
- ✅ Читаемее для дизайнеров
- ✅ Меньше кода (v-model, модификаторы)
- ✅ Явное разделение логики и разметки
- ✅ Компилятор оптимизирует
React JSX:
- ✅ Полная мощь JS в разметке
- ✅ Легче типизировать (TS)
- ✅ IDE-поддержка из коробки
- ✅ Один язык везде
Порог входа
Vue проще для тех, кто знает HTML.
React проще для тех, кто уже пишет на JS.
Итог
- Vue — HTML + директивы
- React — JSX (JS + разметка)
- Vue короче для форм и условий
- React гибче для сложной логики
Дальше — Composition API vs хуки.