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

Использование шаблонов в Vue js для построения интерфейсов

Автор

Олег Марков

Введение

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

Что такое шаблон во Vue.js

Шаблон во Vue — это кусок разметки (HTML), который описывает, как должен выглядеть компонент или часть интерфейса. Эти шаблоны расширены возможностями обработки данных: они поддерживают подстановку переменных, выражения, управляющие конструкции (например, условные блоки), события и многое другое.

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

Основы работы с шаблонами

Основной синтаксис шаблонов

Шаблон обычно находится внутри блока <template>. Пример самого простого компонента:

<template>
  <div>
    <h1>{{ title }}</h1> <!-- Интерполяция переменной -->
    <p>Добро пожаловать!</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: 'Пример заголовка'
    }
  }
}
</script>

В этом примере мы используем двойные фигурные скобки {{ }} для вывода значения переменной title. Как только значение этой переменной меняется, Vue тут же обновляет отображение в браузере. Видите, насколько это просто?

Интерполяция данных

Вы можете подставлять любые данные из вашей модели прямо в шаблон:

<p>Сегодня: {{ new Date().toLocaleDateString() }}</p>

Также доступны все свойства и методы объекта компонента:

<span>Количество: {{ count }}</span>

Ограничения есть: внутри {{ }} можно использовать только короткие однострочные выражения. Например, вот такой пример работать не будет:

{{ let a = 1; a + 2 }} <!-- Ошибка! Так нельзя -->

Динамические атрибуты с помощью v-bind

Если вам нужно сделать значение атрибута динамическим, используйте директиву v-bind:

<img v-bind:src="imageUrl" alt="Фото"> <!-- Значение src — динамическое -->

Укороченная запись: html <img :src="imageUrl" alt="Фото">

Обработка событий с помощью v-on

Vue делает обработку событий очень простой. Пример с кнопкой:

<button v-on:click="increaseCounter">Увеличить</button>
<!-- или сокращенно -->
<button @click="increaseCounter">Увеличить</button>

Здесь при клике вызывается метод increaseCounter, который вы определяете внутри компонента.

Управляющие конструкции: v-if, v-else, v-for

Условные конструкции
Иногда надо отобразить элемент только, если выполнено некоторое условие. Для этого есть директивы v-if, v-else-if, v-else:

<p v-if="isLoggedIn">Приветствуем, пользователь!</p>
<p v-else>Пожалуйста, войдите в систему.</p>

Циклы
Если у вас есть массив, вы можете вывести его элементы с помощью v-for:

<ul>
  <li v-for="(item, idx) in items" :key="idx">{{ item.name }}</li>
</ul>

Vue требует атрибут :key, чтобы оптимально отслеживать изменения.

Обработка пользовательского ввода: v-model

Давайте посмотрим, как двустороннее связывание данных решается с помощью v-model:

<input v-model="username" placeholder="Введите имя">
<p>Вы ввели: {{ username }}</p>

Каждый раз, когда пользователь что-то вводит, переменная username сразу же обновляется.

Работа с вложенными шаблонами и компонентами

Шаблоны для дочерних компонентов

Шаблоны можно вкладывать друг в друга через использование компонентов. Предположим, у вас есть компонент Button:

<!-- MyButton.vue -->
<template>
  <button :class="type">{{ label }}</button>
</template>

<script>
export default {
  props: ['label', 'type'],
}
</script>

Теперь вы используете этот компонент в шаблоне другого компонента:

<MyButton label="Сохранить" type="primary" />

Так вы легко структурируете проект из множества переиспользуемых компонентов, каждый со своим шаблоном.

Слоты: шаблоны с возможностью пользовательской вставки

Vue поддерживает расширенные шаблоны через слоты. Это вырезы внутри шаблона, которые заполняются содержимым вызывающего компонента. Например:

<!-- ParentComponent.vue -->
<template>
  <ChildComponent>
    <span>Переданный из родителя текст</span>
  </ChildComponent>
</template>

<!-- ChildComponent.vue -->
<template>
  <div>
    <slot></slot> <!-- Здесь появится содержимое, переданное из parent -->
  </div>
</template>

Также доступны именованные слоты и scoped slots. Они позволяют более гибко настраивать структуру вложенных компонентов.

Композиция шаблонов

Во Vue вы свободно комбинируете шаблоны из разных компонентов по своему усмотрению, создавая сложные интерфейсы из простых блоков.

Пример: представьте карточку товара с вложенной картинкой, кнопками и описанием — каждый блок можно сделать отдельным компонентом с собственным шаблоном.

Расширенные возможности шаблонов

Встраивание выражений и фильтров

В шаблонах часто применяется обработка данных на лету. Например:

<p>Цена: {{ price | currencyFilter }}</p>

Здесь фильтр currencyFilter может быть написан вами и подключен глобально или локально к компоненту.

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

<p>Цена: {{ formatCurrency(price) }}</p>
methods: {
  formatCurrency(value) {
    return value.toLocaleString() + ' ₽';
  }
}

Динамические компоненты

С помощью директивы <component :is="componentName" /> можно рендерить разные компоненты по условию.

<component :is="currentComponent"></component>
data() {
  return {
    currentComponent: 'LoginForm'
  }
}

Как только в currentComponent окажется другое имя — например, 'RegisterForm', — Vue моментально поменяет видимый шаблон.

Фрагменты

Во Vue 3 появилась поддержка фрагментов — теперь шаблон может возвращать не единственный корневой элемент, а сразу несколько:

<template>
  <header>...</header>
  <main>...</main>
  <footer>...</footer>
</template>

Во Vue 2 требовался единственный корневой тег.

Условный рендеринг: v-show

v-if удаляет или добавляет элемент в DOM полностью, а v-show просто переключает CSS-свойство display. Смотрите пример:

<p v-if="shouldShow">Этот элемент появится или исчезнет из DOM</p>
<p v-show="shouldShow">Этот элемент всегда в DOM, но скрыт через CSS</p>

Выбор между этими директивами зависит от того, насколько часто нужно переключать видимость и важна ли оптимизация производительности.

Ограничения и подводные камни шаблонов во Vue

Только выражения, не инструкции

Внутри двойных скобок нельзя использовать конструкции вроде if, for или объявлять новые переменные:

{{ let x = 10 }} <!-- Это не сработает -->

Работа с объектами и массивами

Vue не отслеживает добавление новых свойств у объектов или новые индексы у массивов так, чтобы они были реактивными (во Vue 2). Поэтому лучше заранее определять все необходимые свойства.

Безопасность: никакого HTML-инъектирования

По умолчанию, если вы передаёте строку в шаблон, она автоматически экранируется:

<p>{{ unsafeString }}</p>

Если хочется позволить рендерить HTML, используйте директиву v-html, но будьте крайне осторожны:

<p v-html="rawHtml"></p>

Открывайте доступ только к доверенным данным, чтобы не допустить XSS-уязвимостей.

Одиночный корневой элемент (Vue 2)

До Vue 3 в шаблоне разрешался только один корневой тег:

<template>
  <div>
    <!-- Всё содержимое здесь -->
  </div>
</template>

В Vue 3 это ограничение убрали.

Практические советы по использованию шаблонов

  • Читайте официальную документацию по директивам: каждый год появляются новые возможности и синтаксические удобства.
  • Разбивайте крупные шаблоны на небольшие компоненты: это улучшает читаемость, поддержку и переиспользуемость.
  • Всегда задавайте атрибут key в циклах v-for — это критически важно для производительности.
  • Для сложных условий используйте вычисляемые свойства вместо длинных выражений в шаблоне.
  • Не забывайте про тестирование шаблонов: иногда из-за неправильной работы условий или типов может всё поломаться.

Заключение

Шаблоны во Vue.js — это мощный и удобный инструмент для построения динамичных, реактивных интерфейсов. Они предоставляют декларативный способ описания UI с помощью расширенного синтаксиса HTML, поддерживают динамические данные, условия, циклы, обработку событий и двустороннее связывание. Освоив шаблоны и их возможности, вы сможете строить надёжные и масштабируемые интерфейсы, легко разбивая их на отдельные компоненты и повторно используя код.

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

Как использовать условный класс для элемента в шаблоне Vue?

Вы можете использовать объект внутри директивы :class:

<div :class="{ active: isActive, disabled: !isEnabled }">
  Элемент с условиями по классам
</div>
  • active будет добавлен, если переменная isActive истинна.
  • disabled появляется, если isEnabled ложно.

Как передать данные из родителя в дочерний компонент?

Используйте свойство props:

<!-- В родителе -->
<ChildComponent :title="parentTitle" />

<!-- В дочернем компоненте -->
props: ['title']

Как динамически изменить имя компонента в <component :is="...">?

Создайте переменную в data, присваивайте ей строку — имя нужного компонента:

data() {
  return {
    current: 'FormA'
  }
}
<component :is="current" />

Меняйте current, чтобы подгружать другие компоненты.

Почему v-for требует атрибут key?

Без key Vue не может надёжно отличать элементы списка при изменениях. Для правильной diff-логики и обновлений DOM всегда пишите уникальное :key для каждого элемента списка:

<li v-for="item in items" :key="item.id">{{ item.text }}</li>

Как сделать вложенные шаблоны более читаемыми?

Разбивайте сложные шаблоны на небольшие компоненты, используйте именованные и scoped слоты для гибкой передачи разметки. Всегда старайтесь держать шаблон одного компонента компактным — до 30-40 строк, если это возможно.

Стрелочка влевоТипизация и использование TypeScript в VuejsИспользование Swiper для создания слайдеров в VueСтрелочка вправо

Постройте личный план изучения Vue до уровня Middle — бесплатно!

Vue — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по 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 с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на 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 в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueПонимание и использование 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
Открыть базу знаний

Лучшие курсы по теме

изображение курса

Vue 3 и Pinia

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

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