Программирование HTML Директивы шаблона Vue Wed, February 11 2026  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


Директивы шаблона Vue Печать
Добавил(а) microsin   

Директивы в Vue — это специальные HTML-атрибуты с префиксом `v-`, которые добавляют реактивное поведение элементам в шаблоне. Они являются одной из ключевых возможностей фреймворка. Помимо v-html, существует несколько основных категорий директив. Вот список основных директив с кратким описанием:

Категория Директива Краткое описание и ключевой эффект
Условный рендеринг v-if, v-else-if, v-else Условное отображение/удаление элемента из DOM. v-if — полноценное условное создание/уничтожение.
v-show Условное отображение через CSS-свойство `display: none`. Элемент остаётся в DOM.
Работа со списками v-for Рендеринг списка элементов на основе массива или объекта. Обязательно требует указания `:key`.
Обработка событий v-on (или `@`) Прослушивание событий DOM (click, input и др.) и вызов методов или выражений. Например, `@click="handleClick"`.
Связывание данных v-bind (или `:`) Динамическое связывание атрибута или prop с данными. Например, `:id="dynamicId"`, `:class="{ active: isActive }`.
Двустороннее связывание [3] v-model Двустороннее связывание для элементов форм (input, textarea, select) и компонентов.
Отрисовка разметки v-html Вставка HTML-кода (осторожно: риск XSS-атак).
v-text Вставка текста (аналогично `{{ }}`, но заменяет всё содержимое элемента).
v-once Одноразовый рендер элемента и его дочерних компонентов (данные не будут обновляться).
v-memo (Vue 3.2+) Мемоизация поддерева, предотвращает обновления, если массив зависимых значений не изменился.
Работа с компонентами v-slot (или `#`) Определение слотов (областей содержимого) в компонентах.
Особые/редкие v-pre Пропуск компиляции для элемента и всех его потомков (отображает сырой `{{ }}`).
v-cloak Скрытие шаблона до завершения компиляции Vue (используется с CSS `[v-cloak] { display: none }`).

Проп (prop) в Vue — это пользовательский атрибут, который родительский компонент передаёт дочернему компоненту. Пропы — это основной механизм одностороннего потока данных сверху вниз.

[Простая аналогия]

Представьте, что компонент — это функция, а пропсы — это её аргументы. Родитель "вызывает" дочерний компонент, передавая ему данные (аргументы/пропсы), а компонент использует их для своего отображения и логики.

Как это работает на практике:

1. В родительском компоненте вы передаёте данные как атрибут HTML:

< !-- Родительский компонент Parent.vue передаёт проп `title` -->
< template>
  < ChildComponent :title="parentTitle" :count="5" />
< /template>
< script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return { parentTitle: 'Привет от родителя!' }
} } < /script>

2. В дочернем компоненте вы явно объявляете пропсы и используете их как обычные переменные:

< !-- Дочерний компонент ChildComponent.vue получает пропсы -->
< template>
  < div>
    < h1>{{ title }}< /h1> < !-- Используем проп -->
    < p>Передано чисел: {{ count }}< /p>
  < /div>
< /template>
< script>
export default {
props: {
// Объявление пропа с проверкой типа
title: { type: String, required: true },
// Более простая запись, если проверка не нужна
count: Number
},
mounted() {
console.log(this.title); // Доступно как this.title
} } < /script>

[Ключевые характеристики пропсов]

Характеристика Объяснение Почему это важно
Односторонний поток Данные текут только от родителя к ребёнку. Дочерний компонент не может напрямую изменять полученный проп. Гарантирует предсказуемость. Источник данных — всегда родитель.
Реактивность [2] Если родитель изменяет значение пропса, дочерний компонент автоматически получит обновление. Изменения синхронизируются без дополнительных усилий.
Валидация Можно задавать тип (`String`, `Number`, `Array`, `Object`), обязательность (`required: true`), значение по умолчанию (`default`), кастомную функцию-валидатор. Помогает избегать ошибок, делает интерфейс компонента понятным для других разработчиков.
Передача через v-bind (`:`) Динамические значения передаются через `:propName="expression"`. Статичные значения — `propName="staticValue"`. `v-bind` или его краткая запись `:` — это именно то, о чём шла речь в описании директив.

[Пропсы vs локальные данные (`data()`)]

Пропсы (`props`) Локальные данные (`data()`)
Получаются извне (от родителя) Определяются внутри компонента
Нельзя изменять напрямую (рекомендация) Можно свободно изменять через `this.имя_данных`
Используются для конфигурации компонента, передачи информации Используются для внутреннего состояния компонента (флаги, временные данные)

[Частый паттерн: создание "локальной копии"]

Поскольку напрямую менять проп нельзя, часто создают локальную переменную на его основе:

export default {
props: ['initialCounter'], data() {
return {
localCounter: this.initialCounter // Инициализируем локальные данные пропом
}
} }

[Почему это важно в контексте `v-bind`]

Директива `v-bind` (или `:`) — это основной способ передачи динамических пропсов. Без неё в атрибут попадёт просто строка "parentTitle", а не значение переменной.

`title="parentTitle"` → Проп получит строку "parentTitle"

`:title="parentTitle"` → Проп получит значение переменной `parentTitle` (например, "Привет от родителя!")

Таким образом, проп — это параметр компонента, а `v-bind` — "инструмент доставки" этого параметра от родителя к ребёнку.

[Подробнее о ключевых директивах]

1. Условный рендеринг: отличие v-if и v-show

v-if — "ленивая" директива. Если условие ложно, элемент не создаётся в DOM. Идеально для дорогих в рендере элементов или когда условие меняется редко.

v-show — элемент всегда создаётся в DOM, но переключается через CSS (`display`). Лучше использовать для частых переключений, так как переключение дешевле.

2. Работа со списками: v-for

Самая мощная директива для рендеринга данных. Умеет работать с массивами, объектами и числами. Ключевое правило: всегда указывайте уникальный `:key` для оптимальной реактивности.

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

// App.vue
< script setup>
import { ref } from "vue"

const visible = true;
const arr = ref(["Света", "Даша", "Андрей"]); < /script>
< template> < ul> < li v-for="item in arr" v-if="visible"> {{ item }} < /ul> < /template>

v-if вместе с v-for. В этом примере используется v-if только для того, чтобы напомнить о факте, что v-if при отображении имеет преимущество перед v-for.

В примере выше ключ (key) для v-for не используется, что для этого случая работает, но в общем неправильно. Ключ в директиве v-for в Vue это специальный атрибут, который помогает Vue идентифицировать каждый элемент списка при его обновлении.

[Зачем нужен ключ?]

1. Эффективное обновление DOM (Document Object Model). Без ключа Vue перерисовывает весь список при изменениях. С ключом Vue может:

- Определить, какие элементы изменились.
- Переместить существующие элементы вместо перерисовки.
- Удалить только те элементы, которые исчезли

2. Сохранение состояния компонентов. Ключ помогает Vue отслеживать состояние компонентов в списке:

< !-- Без ключа: при изменении порядка элементы теряют состояние -->
< div v-for="item in items">
  < input v-model="item.value"> < !-- Состояние может "перепутаться" -->
< /div>

< !-- С ключом: состояние сохраняется правильно --> < div v-for="item in items" :key="item.id"> < input v-model="item.value"> < !-- Состояние привязано к конкретному элементу --> < /div>

[Правила использования ключей]

✅ Правильно:

< !-- Уникальный идентификатор -->
< div v-for="user in users" :key="user.id">
  {{ user.name }}
< /div>

< !-- Индекс (только если список статичен и не изменяется) --> < div v-for="(item, index) in items" :key="index"> {{ item }} < /div>

❌ Неправильно:

< !-- Избегайте index как ключ для динамических списков -->
< div v-for="(item, index) in items" :key="index">
  < !-- Проблема: при удалении/добавлении элементов ключи перепутаются -->
< /div>

< !-- Не используйте нестабильные значения --> < div v-for="item in items" :key="Math.random()"> < !-- Ключ будет меняться каждый рендер --> < /div>

Пример проблемы без ключа:

// Исходный список
items: ['A', 'B', 'C']

// После удаления 'B' Vue может:
// 1. Удалить 'B' и оставить 'A', 'C' (правильно)
// 2. Удалить 'C' и переименовать 'B' в 'C' (если нет ключа)

Рекомендации:

1. Всегда используйте :key для v-for.
2. Используйте уникальные стабильные идентификаторы (id из базы данных).
3. Избегайте index как ключ, если список может меняться (сортировка, фильтрация, добавление, удаление).
4. Ключи должны быть уникальными среди siblings (элементов одного уровня).

Ключи — это механизм оптимизации, который делает ваше приложение более эффективным и предсказуемым при работе со списками.

3. Двустороннее связывание: v-model

"Синтаксический сахар" для связки `:value` + `@input`. В Vue 3 её можно кастомизировать для компонентов через опции `modelValue` и `update:modelValue`. Для разных типов input (`checkbox`, `select`) работает "из коробки".

4. Модификаторы директив

Многие директивы (особенно v-on и v-model) поддерживают модификаторы — специальные постфиксы через точку для изменения поведения.

- Для v-on: `@click.stop` (остановка всплытия), `@keyup.enter` (срабатывание на Enter), `@submit.prevent` (отмена перезагрузки страницы).

- Для v-model: `v-model.lazy` (обновление по событию `change`), `v-model.number` (приведение к числу), `v-model.trim` (удаление пробелов).

[Краткие рекомендации по выбору]

- Для условного показа часто переключаемого элемента → v-show.
- Для условного рендеринга тяжёлого элемента или при принципиальном отсутствии в DOM → v-if.
- Для рендеринга списков → v-for с обязательным `:key`.
- Для элементов форм → v-model.
- Для динамических атрибутов, классов, стилей → v-bind (`:`).
- Для обработки действий пользователя → v-on (`@`).

Это основные встроенные директивы. Также вы можете создавать собственные директивы с помощью `app.directive()` для низкоуровневых манипуляций с DOM.

Пример v-html. Директива v-html используется для генерации динамически изменяемого кода html. Например, если создать переменную JavaScript:

let mylink = "< a href='https://microsin.ru'>Мой сайт< /a>"

.. и вставить ссылку на эту переменную в шаблон:

< template>
  < header>Лого< /header>
  < main>{{ mylink }}< /main>
  < footer>Футер< /footer>
< /template>

.. то при вставке этой переменной в шаблон просто отобразится текст содержимого переменной mylink.

Vue template directives fig01

Чтобы вместо этого текста была сформирована ссылка, примените директиву v-html следующим образом:

  < main v-html="mylink">< /main>

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

Vue template directives fig02

Пример v-bind для привязки атрибута. С помощью директивы v-bind (или ':') привязывают атрибуты к элементам шаблона.

< script setup>
let mylink = "< a href='https://microsin.ru'>Мой сайт< /a>";
const color = "red" < /script>
< template> < header>Лого< /header> < main v-html="mylink" v-bind:class="color">< /main> < footer>Футер< /footer> < /template>
< style scoped> < /style>

В результате получится вот такой код HTML:

< !DOCTYPE html>
< !-- saved from url=(0022)http://localhost:5173/ --> < html lang="en"> < head> < meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> < script type="module" src="./vue-app_files/client">< /script> < link rel="icon" type="image/svg+xml" href="http://localhost:5173/vite.svg"> < meta name="viewport" content="width=device-width, initial-scale=1.0"> < title>vue-app< /title> < style type="text/css" data-vite-dev-id="/home/username/vue-app/src/style.css">:root {
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; } < /style> < /head> < body> < div id="app" data-v-app=""> < header>Лого< /header> < main class="red"> < a href="https://microsin.ru/">Мой сайт< /a> < /main> < footer>Футер< /footer> < /div> < script type="module" src="./vue-app_files/main.js">< /script> < /body> < /html>

Ключевое слово v-bind можно просто заменить двоеточием:

< main v-html="mylink" :class="color">< /main>

Пример v-bind для привязки идентификатора. Можно динамически добавлять идентификаторы:

< script setup>
const id = "blue" < /script>
< template> < main :id="id">Контент< /main> < /template>
< style scoped> < /style>

Сокращенная запись того же самого:

  < main :id>Контент< /main>

В результате получится код:

< body>
  < div id="app" data-v-app="">
    < main id="blue">Контент< /main>
  < /div>
  < script type="module" src="./vue-app_files/main.js">< /script>
< /body>

[Ссылки]

1. Vue 3, быстрый старт.
2Vue: реактивность.
3. Vue: двустороннее связывание.

 

Добавить комментарий


Защитный код
Обновить

Top of Page