Механизм provide/inject в Vue.js предназначен для
передачи данных от родительского компонента к потомкам на любом уровне
вложенности, минуя цепочку props. Он позволяет создавать
зависимости, которые будут доступны всем потомкам, не требуя явной
передачи через каждый уровень компонентов.
В родительском компоненте используется свойство provide,
которое может быть объектом или функцией:
export default {
provide() {
return {
user: this.user,
theme: 'dark'
};
},
data() {
return {
user: { name: 'Иван', age: 30 }
};
}
}
Ключевые моменты:
provide — функция, она получает контекст
компонента (this), что позволяет предоставлять реактивные
данные.provide — объект, данные являются статическими и
не реактивными.Дочерний компонент получает данные с помощью свойства
inject:
export default {
inject: ['user', 'theme'],
mounted() {
console.log(this.user.name); // 'Иван'
console.log(this.theme); // 'dark'
}
}
Особенности:
inject может быть массивом строк (имена ключей) или
объектом, где ключи задают локальные имена, а значения — имена из
provide.inject: {
locale: {
from: 'locale',
default: 'ru-RU'
}
}
По умолчанию простые объекты, переданные через provide,
не являются реактивными. Для реактивности следует использовать
reactive или ref:
import { reactive, ref, provide } from 'vue';
export default {
setup() {
const user = reactive({ name: 'Иван', age: 30 });
const theme = ref('dark');
provide('user', user);
provide('theme', theme);
return {};
}
}
В дочернем компоненте изменения этих данных будут автоматически отслеживаться:
import { inject } from 'vue';
export default {
setup() {
const user = inject('user');
const theme = inject('theme');
function changeName() {
user.name = 'Пётр';
theme.value = 'light';
}
return { user, theme, changeName };
}
}
Provide/Inject поддерживает передачу данных через несколько уровней компонентов. Потомок может инжектировать данные из любого родителя выше в иерархии, при этом промежуточные компоненты не обязаны ничего знать о передаваемых данных:
// Родитель
provide('config', { apiUrl: '/api' });
// Глубокий потомок
inject('config'); // доступ к { apiUrl: '/api' }
Если несколько родителей предоставляют одинаковый ключ, то инжектируется ближайший по иерархии родитель.
Глобальные настройки Передача темы, локали, API-конфигураций, токенов авторизации.
Менеджеры состояния модулей Использование provide/inject для предоставления контекста состояния без подключения Vuex или Pinia.
Повторно используемые компоненты Компоненты библиотеки могут получать конфигурации через inject, не завися от конкретного родителя.
| Механизм | Передача данных | Глубина | Реактивность по умолчанию |
|---|---|---|---|
| Props | Родитель → ребёнок | 1 уровень | Да |
| Provide/Inject | Родитель → потомки | Любая | Нет (только через reactive/ref) |
| Vuex/Pinia | Глобально | Любая | Да |
Provide/Inject лучше использовать для небольших зависимостей и контекста, а не для глобального состояния.
ref или
reactive, если данные будут меняться.inject для указания
значений по умолчанию.Механизм provide/inject в Vue.js является гибким инструментом для передачи данных через иерархию компонентов, обеспечивая лёгкость доступа к зависимостям и упрощая управление контекстом приложения без необходимости передачи данных через каждый уровень компонентов.