0Pricing
Frontend Academy · Урок

provide() и inject() для внедрения зависимостей

Предоставляйте значения в компоненте-предке и внедряйте их глубоко в дерево, избегая последовательной передачи свойств без полноценной библиотеки управления состоянием

«provide() и inject() для внедрения зависимостей» — бесплатный урок Frontend Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.

Проблема передачи свойств через цепочку компонентов

Иногда данные находятся в компоненте верхнего уровня и должны попасть к глубоко вложенному потомку. Передавать их через каждый промежуточный компонент — то есть использовать передачу свойств через цепочку компонентов — утомительно и ненадёжно.

provide() — объявление значения

Предок вызывает provide(key, value) в setup(). Значение становится доступным всем потомкам.

<!-- ParentComponent.vue -->
<script setup>
import { provide, ref } from 'vue';

const theme = ref('dark');
provide('theme', theme);
</script>

inject() — получение значения

Любой потомок вызывает inject(key), чтобы прочитать это значение.

<!-- DeepChild.vue -->
<script setup>
import { inject } from 'vue';

const theme = inject('theme');
</script>

<template>
  <div :class="theme">Theme is: {{ theme }}</div>
</template>

Реактивность с ref/reactive

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

// Parent
const user = reactive({ name: 'Alice', role: 'admin' });
provide('user', user);

// Anywhere descendant
const user = inject('user');
user.role; // 'admin' — reactive

Символьные ключи для предотвращения конфликтов

Строковые ключи могут конфликтовать в больших приложениях. Символы гарантируют уникальность — определяйте их в общем файле.

// keys.ts
export const ThemeKey = Symbol('theme');
export const UserKey  = Symbol('user');

// Parent
provide(ThemeKey, ref('dark'));
// Child
const theme = inject(ThemeKey);

Поддержка TypeScript

Используйте InjectionKey<T>, чтобы обеспечить проверку типов с обеих сторон.

import type { InjectionKey, Ref } from 'vue';

export const ThemeKey: InjectionKey<Ref<string>> = Symbol('theme');

// Provider:
provide(ThemeKey, ref('dark'));

// Consumer (type-checked):
const theme = inject(ThemeKey); // Ref<string> | undefined

Значения по умолчанию

Если ни один предок не предоставил ключ, inject возвращает undefined, если не передать значение по умолчанию.

const theme = inject('theme', 'light'); // default if missing
const lazy  = inject('user', () => createDefaultUser(), true); // factory

Доступные только для чтения значения

Чтобы потомки не могли изменять общее состояние, оберните его в readonly().

import { readonly } from 'vue';

const user = reactive({ name: 'Alice' });
provide('user', readonly(user));
// Children can read but cannot mutate

Предоставление на уровне приложения

Предоставляйте значения на уровне приложения, чтобы они были доступны повсюду — это полезно для плагинов.

// main.ts
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);
app.provide('apiClient', new ApiClient());
app.mount('#app');

Обёртка-компонуемая функция

Оберните provide/inject в компонуемую функцию, чтобы сделать API для использования более удобным.

// useTheme.ts
import { inject, type InjectionKey, type Ref } from 'vue';

export const ThemeKey: InjectionKey<Ref<string>> = Symbol('theme');

export function useTheme() {
  const theme = inject(ThemeKey);
  if (!theme) throw new Error('useTheme: no provider in tree');
  return theme;
}

provide/inject и Pinia

provide/inject: лёгкий подход без библиотеки, идеально подходит для значений в стиле плагинов — темы, локали и текущего пользователя. Pinia: полноценное управление состоянием с DevTools, оптимальное для общего состояния приложения со сложными обновлениями.

Проверьте себя

Как рекомендуется предотвращать конфликты ключей при использовании provide/inject в большом приложении Vue?

Итоги: provide/inject

Предок предоставляет значение, потомок получает его — передача свойств через цепочку компонентов не нужна. Реактивные значения (ref/reactive) распространяются реактивно. Символьные ключи и InjectionKey обеспечивают проверку типов и отсутствие конфликтов при внедрении. Значение по умолчанию передаётся вторым аргументом inject. readonly() предотвращает изменение. Предоставление на уровне приложения удобно для плагинов, используемых во всём приложении. Это лёгкая альтернатива Pinia для значений в стиле плагинов.

Часто задаваемые вопросы

Урок «provide() и inject() для внедрения зависимостей» бесплатный?

Да — полный текст урока «provide() и inject() для внедрения зависимостей» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.

Чему я научусь в уроке «provide() и inject() для внедрения зависимостей»?

Предоставляйте значения в компоненте-предке и внедряйте их глубоко в дерево, избегая последовательной передачи свойств без полноценной библиотеки управления состоянием Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Frontend Academy?

Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «provide() и inject() для внедрения зависимостей»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Frontend Academy?

Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. provide() и inject() для внедрения зависимостей
  2. Асинхронные компоненты и Suspense
  3. Пользовательские директивы
  4. Система плагинов: app.use()
← Назад к Frontend Academy