Урок 03

Шаблоны 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 хуки.