Передача данных через props

Props (properties) — механизм передачи данных от родительского компонента к дочернему. Архитектура Vue.js строится на принципе однонаправленного потока данных: родитель владеет состоянием, дочерний компонент получает это состояние в виде входных параметров и не изменяет его напрямую.

Такой подход упрощает сопровождение кода, делает поведение компонентов предсказуемым и предотвращает скрытые побочные эффекты.


Базовый синтаксис передачи props

Передача данных осуществляется через атрибуты компонента в шаблоне родителя.

<ChildComponent title="Заголовок" />

В дочернем компоненте props объявляются явно:

export default {
  props: ['title']
}

После объявления значение становится доступным в шаблоне и логике компонента:

<h1>{{ title }}</h1>

Передача динамических значений

Для передачи переменных используется директива v-bind или её сокращённая форма :.

<ChildComponent :count="items.length" />
export default {
  props: ['count']
}

Без v-bind значение всегда интерпретируется как строка.


Именование props

Во Vue применяются разные стили именования:

  • В JavaScriptcamelCase
  • В HTML-шаблонахkebab-case
props: ['userName']
<ChildComponent user-name="Ivan" />

Vue автоматически сопоставляет эти форматы.


Типизация props

Для повышения надёжности props могут объявляться в виде объекта с указанием типа.

export default {
  props: {
    title: String,
    count: Number,
    isActive: Boolean
  }
}

Поддерживаемые типы:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Function
  • Date
  • Symbol

Обязательные props и значения по умолчанию

Props можно пометить как обязательные и задать значения по умолчанию.

props: {
  title: {
    type: String,
    required: true
  },
  count: {
    type: Number,
    default: 0
  }
}

Для объектов и массивов default должен быть функцией:

props: {
  options: {
    type: Object,
    default() {
      return {}
    }
  }
}

Это предотвращает совместное использование одного и того же объекта между экземплярами компонентов.


Валидация props

Vue позволяет задавать пользовательские правила проверки.

props: {
  status: {
    type: String,
    validator(value) {
      return ['success', 'error', 'loading'].includes(value)
    }
  }
}

При нарушении правил Vue выводит предупреждение в консоль в режиме разработки.


Реактивность props

Props являются реактивными: при изменении значения в родительском компоненте дочерний автоматически обновляется.

<ChildComponent :count="counter" />

Изменение counter в родителе приводит к перерисовке дочернего компонента.


Запрет на изменение props внутри компонента

Прямое изменение props считается архитектурной ошибкой.

this.count++ // антипаттерн

Причины:

  • нарушение однонаправленного потока данных
  • непредсказуемое поведение
  • сложность отладки

Vue выводит предупреждение при попытке изменить prop напрямую.


Корректные способы работы с изменяемыми данными

Локальная копия props

Если требуется изменяемое значение, создаётся локальное состояние:

props: {
  count: Number
},
data() {
  return {
    localCount: this.count
  }
}

Вычисляемые свойства

Для трансформации входных данных:

props: ['price'],
computed: {
  priceWithTax() {
    return this.price * 1.2
  }
}

Boolean props и сокращённый синтаксис

Boolean props имеют особое поведение.

<ChildComponent disabled />
props: {
  disabled: Boolean
}

Наличие атрибута автоматически интерпретируется как true.


Передача функций через props

Props могут содержать функции, что позволяет передавать поведение:

<ChildComponent :onS ave="saveData" />
props: {
  onSave: Function
}

На практике чаще используется механизм событий (emit), так как он лучше отражает архитектуру Vue.


Props и события: разграничение ответственности

Props:

  • передают данные вниз по иерархии
  • не изменяются внутри компонента

События (emit):

  • передают сигналы вверх
  • используются для уведомления родителя об изменениях

Типовой шаблон взаимодействия:

<ChildComponent :value="text" @update="text = $event" />

Модификатор .sync и его особенности

.sync — синтаксический сахар для связки props и событий.

<ChildComponent :value.sync="text" />

Эквивалентно:

<ChildComponent
  :value="text"
  @update:value="text = $event"
/>

Использование .sync ограничено и не рекомендуется для сложной логики, так как может скрывать поток данных.


Передача сложных структур данных

Объекты и массивы передаются по ссылке:

<ChildComponent :user="user" />

Изменение вложенных свойств влияет на родителя, что требует осторожности. Для защиты данных применяется:

  • копирование структуры
  • неизменяемые операции
  • строгая договорённость об ответственности компонентов

Деструктуризация props в Composition API

В Composition API props передаются в функцию setup.

export default {
  props: {
    title: String
  },
  setup(props) {
    console.log(props.title)
  }
}

Деструктуризация лишает реактивности:

const { title } = props // не реактивно

Корректный вариант:

import { toRefs } from 'vue'

const { title } = toRefs(props)

Ограничения props и альтернативы

Props не предназначены для:

  • передачи данных через большое количество уровней вложенности
  • глобального состояния
  • двустороннего редактирования сложных структур

В таких случаях применяются:

  • provide / inject
  • глобальные хранилища состояния
  • композиционные функции

Лучшие практики использования props

  • всегда объявлять props явно
  • использовать типизацию и валидацию
  • не изменять props напрямую
  • минимизировать количество props
  • разделять данные и поведение
  • поддерживать ясный контракт между компонентами

Чёткое понимание механизма props является основой масштабируемой и поддерживаемой архитектуры Vue-приложений.