логотип PurpleSchool
логотип PurpleSchool

Примеры использования JSX во Vue

Автор

Олег Марков

Введение

Vue традиционно ассоциируется с использованием шаблонов (template), которые легко читаются даже теми, кто только начинает работать с этим фреймворком. Однако не все знают, что Vue прекрасно работает и с JSX – синтаксисом, популярным среди разработчиков React. JSX позволяет писать разметку непосредственно внутри JavaScript, даёт мощную динамику, улучшает возможности композиции, да и просто нравится многим разработчикам, привыкшим к таким шаблонам.

В этой статье я покажу, как на практике использовать JSX во Vue – вы увидите, как это настраивается, какие подходы к организации кода доступны и какие задачи проще решать именно через JSX. Уверен, что после нескольких примеров вы без труда сможете применять эту технологию в своих проектах.

Настройка поддержки JSX во Vue

Как подключить поддержку JSX

По умолчанию во Vue (особенно в версиях Vue 2 и 3) нужно явно добавить поддержку JSX через плагины для сборщиков типа Vite или Webpack.

Для Vue 3 с Vite

  1. Установите нужный плагин:
npm install @vitejs/plugin-vue-jsx --save-dev
  1. Подключите плагин в vite.config.js:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';

export default defineConfig({
  plugins: [vue(), vueJsx()], // Подключаем оба плагина
});

Для Vue 3 с Webpack

Используйте Babel плагин для JSX:

npm install @vue/babel-plugin-jsx --save-dev

И добавьте его в настройки Babel (например, в babel.config.js):

module.exports = {
  plugins: ['@vue/babel-plugin-jsx'],
};

Применение в SFC (Single File Components)

Вместо секции <template> используйте <script lang="jsx"> или просто .jsx или .tsx файл:

// Пример MyComponent.jsx
import { defineComponent } from 'vue';

export default defineComponent({
  setup() {
    return () => <div>Привет из JSX!</div>;
  }
});

Обратите внимание: весь рендеринг теперь происходит через функцию setup, которая возвращает функцию рендера.

Базовый синтаксис JSX во Vue

Как объявлять элементы

JSX позволяет объявлять структуру компонентов прямо внутри JS:

return () => <h1>Заголовок через JSX</h1>;

Можно вкладывать элементы:

return () => (
  <section>
    <h1>Внутри секции</h1>
    <p>Описание компонента</p>
  </section>
);

Для динамических атрибутов используйте фигурные скобки:

const title = "Это динамический заголовок";
return () => <h1>{title}</h1>;

Использование условных операторов и циклов

В JSX часто применяют тернарный оператор и map:

const show = true;
return () => (
  <div>
    {show ? <span>Видно</span> : <span>Скрыто</span>}
  </div>
);

Генерация списка на основе массива:

const items = ['яблоко', 'банан', 'апельсин'];
return () => (
  <ul>
    {items.map((fruit, i) => (
      <li key={i}>{fruit}</li>
    ))}
  </ul>
);

Передача и обработка props, событий и слотов

Передача props

В JSX props передаются как атрибуты элемента:

const MyButton = (props) => <button>{props.label}</button>;

// Использование
<MyButton label="Нажми меня" />

Обработка событий

События работают почти так же, как в React или обычном Vue, только именование событий — в верблюжьем стиле:

<button onClick={() => alert("Клик по кнопке!")}>Кликни!</button>

Если вы передаёте функцию, не забывайте про стрелочные функции или bind.

Использование слотов

Иногда в JSX их называют "children". Пример простой передачи слота:

const Panel = (props, { slots }) => (
  <div class="panel">
    {slots.default ? slots.default() : null}
  </div>
);
// Использование
<Panel>
  <p>Контент панели</p>
</Panel>

В Vue 3 c Composition API доступ к слотам осуществляется через второй аргумент setup-функции.

Передача и обработка ref

Для работы с ref используйте директиву ref напрямую:

import { ref } from 'vue';

export default defineComponent({
  setup() {
    const inputRef = ref(null);
    const focusInput = () => {
      inputRef.value && inputRef.value.focus();
    };

    // input связывается с ref
    return () => (
      <>
        <input ref={inputRef} />
        <button onClick={focusInput}>Фокус</button>
      </>
    );
  }
});

Расширенные примеры работы с JSX

Создание динамических компонентов

Смотрите, как можно выбирать компонент для рендеринга на лету:

const DynamicComponent = defineComponent({
  props: {
    type: String // Например, 'input' или 'select'
  },
  setup(props) {
    return () =>
      props.type === 'input'
        ? <input placeholder="Введите текст"/>
        : <select>
            <option>Выберите</option>
          </select>
  }
});
// Использование
<DynamicComponent type="input" />

Обработка событий с передачей параметров

Если нужно передать параметры в обработчик события:

<button onClick={() => handleClick(item.id)}>Удалить</button>

Или использовать bind:

<button onClick={handleClick.bind(null, item.id)}>Удалить</button>

Использование директив v-model в JSX

В Vue 3 появилась поддержка двухсторонней привязки через v-model:

import { ref } from 'vue';

export default defineComponent({
  setup() {
    const name = ref('');
    return () => (
      <input v-model={name.value} />
    );
  }
});

Однако по факту, в чисто JSX-компонентах v-model заменяется на пару props+event:

<input value={name.value} onInput={e => name.value = e.target.value} />

Кастомные директивы (аналог v-if / v-for)

Вместо v-if — используйте обычные условия:

{visible && <div>Покажи меня!</div>}

Вместо v-for — map, как выше.

Пример с динамическими стилями и классами

const isActive = true;
const styles = { color: 'red', fontWeight: 'bold' };
return () => (
  <div class={{ active: isActive, disabled: !isActive }} style={styles}>
    Динамические классы и стили
  </div>
);

Обратите внимание: для классов используйте объект — ключи будут классами, значения — булевы выражения.

Когда выбирать JSX во Vue

Преимущества

  • Гибкость: вся сила JavaScript под рукой, нет ограничений шаблона.
  • Переиспользуемость взаимных блоков разметки: проще строить функции, возвращающие разметку.
  • Динамическая генерация компонентов, вложенные функции: удобно организовывать сложные структуры.

Недостатки

  • Чуть меньше декларативности и простоты для новичков.
  • Шаблоны проще читаются при верстке.
  • Нужно дополнительное подключение плагинов.

Хорошие сценарии для применения JSX

  • Когда компонент действительно сложный и требует много вычисляемой, условно-динамической разметки.
  • Если ваша команда знакома с React и привыкла к схожей организации кода.
  • При необходимости написать множество вспомогательных функций для генерации блоков или часто менять обработчики событий.

Заключение

JSX становится все более уместным выбором в мире Vue для решения задач, когда простые шаблоны уже не справляются с динамикой или требуют слишком сложных вычислений. Вы узнали, как настроить поддержку JSX, как выглядит базовый и расширенный синтаксис, как реализуются типовые и нестандартные шаблонные сценарии с помощью JSX. Свободное сочетание Vue и JSX позволяет вам оставаться продуктивным и реализовывать самые амбициозные задумки.


Частозадаваемые технические вопросы по теме

Как подключить глобальные расширения (например, плагины), если я пишу компоненты только на JSX?

Если вы используете только JSX-компоненты, используйте функцию app.use(plugin) в вашем основном файле (обычно main.js). Это не зависит от синтаксиса компонентов – плагины будут доступны во всей иерархии компонентов, включая те, что на JSX.

Почему мои props не типизируются в JSX, как это делается в типовом Vue SFC?

В JSX можно использовать TypeScript для типизации props: объявите их в defineComponent, а для функциональных компонентов используйте Generic-параметры. Пример:

const MyComponent: FunctionalComponent<{ count: number }> = (props) => <span>{props.count}</span>;

Почему не работают шаблонные директивы (например, v-if, v-for, v-show) в JSX?

JSX-интерпретация не поддерживает директивы прямо — используйте JavaScript-условия, тернарные операторы, циклы map и собственные условия для контролирования вывода.

Как правильно подключать scoped-стили в компонентах на JSX?

Scoped-стили работают на уровне <style scoped> в SFC. Для JSX компонентов используйте CSS-модули, библиотеку CSS-in-JS или глобальные классы. Например, с Vite можно импортировать CSS-модуль и применять классы через объект.

Можно ли использовать JSX в миксинах или директивах?

Да, вы можете описывать render-функции в миксинах или создавать пользовательские директивы для Vue, возвращающие JSX-элементы, если ваш сборщик поддерживает JSX. Подключение ничем не отличается от обычных компонентов.

Стрелочка влевоРуководство по интеграции Vue js в NET проектыГайд по импорту и регистрации компонентов на VueСтрелочка вправо

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Обзор и использование утилит Vue для удобной разработкиРабота с обновлениями компонента и жизненным циклом updateРазрешение конфликтов и ошибок с помощью Vue resolveИспользование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание core функционала Vue и его применениеПонимание и применение Composition API в Vue 3Понимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueИнтеграция Vue с Bitrix для корпоративных решенийНастройка и сборка проектов Vue с использованием современных инструментовРазработка административных панелей на Vue js
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с Vue для современных интерфейсовИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах VueОбработка запросов и асинхронных операций в Vue3 способа улучшить навигацию Vue с push()Понимание и использование provide inject для передачи данных между компонентамиПередача и использование props в Vue 3 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueИспользование хуков жизненного цикла в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitРабота с динамическими компонентами и данными в Vue3 способа манипулирования DOM на VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueРабота с teleport для управления DOM во VueПять шагов по настройке SSR в VuejsИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиРуководство по nextTick для работы с DOMСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний

Отправить комментарий