Skip to main content
Практика завдань

Provide/inject у Vue.js

Що таке provide/inject?

provide та inject — це пара API для передачі даних від батьківського компонент до будь-якого нащадка без явної передачі через пропси на кожному рівні.

Це вирішує проблему "пробивання пропсів" — коли потрібно передавати пропси через багато компонентів.


Основне використання

Composition API

javascript
<!-- App.vue (батьківський) --> <template> <ChildComponent /> </template> <script setup> import { provide, ref } from 'vue' import ChildComponent from './ChildComponent.vue' const theme = ref('dark') provide('theme', theme) </script>
javascript
<!-- GrandchildComponent.vue (нащадок) --> <template> <div :class="theme"> Тема: {{ theme }} </div> </template> <script setup> import { inject } from 'vue' const theme = inject('theme') </script>

Реактивність

Передача реактивних даних

javascript
<!-- App.vue --> <template> <button @click="theme = theme === 'dark' ? 'light' : 'dark'"> Перемкнути тему </button> <ChildComponent /> </template> <script setup> import { provide, ref } from 'vue' const theme = ref('dark') // Передайте ref, а не значення provide('theme', theme) </script>
javascript
<!-- DeepChild.vue --> <template> <div :class="theme"> Поточна тема: {{ theme }} </div> </template> <script setup> import { inject } from 'vue' const theme = inject('theme') // тема автоматично оновиться при зміні </script>

Передача функцій для модифікації

javascript
<!-- App.vue --> <script setup> import { provide, ref } from 'vue' const count = ref(0) const increment = () => { count.value++ } provide('count', count) provide('increment', increment) </script>
javascript
<!-- DeepChild.vue --> <template> <p>Кількість: {{ count }}</p> <button @click="increment">Збільшити</button> </template> <script setup> import { inject } from 'vue' const count = inject('count') const increment = inject('increment') </script>

Значення за замовчуванням

javascript
<script setup> import { inject } from 'vue' // Якщо 'theme' не надано, використовуйте 'light' const theme = inject('theme', 'light') // Значення за замовчуванням як функція const user = inject('user', () => ({ name: 'Гість' })) // Третій параметр - значення обчислюється як фабрика const config = inject('config', () => { return { /* складна логіка */ } }, true) </script>

Символьні ключі

Використання Symbol запобігає конфліктам імен:

javascript
// keys.js export const ThemeKey = Symbol('theme') export const UserKey = Symbol('user')
javascript
<!-- App.vue --> <script setup> import { provide, ref } from 'vue' import { ThemeKey, UserKey } from './keys' const theme = ref('dark') const user = ref({ name: 'John' }) provide(ThemeKey, theme) provide(UserKey, user) </script>
javascript
<!-- Child.vue --> <script setup> import { inject } from 'vue' import { ThemeKey, UserKey } from './keys' const theme = inject(ThemeKey) const user = inject(UserKey) </script>

provide/inject на рівні застосунку

javascript
// main.js import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.provide('apiUrl', 'https://api.example.com') app.provide('appName', 'Мій додаток') app.mount('#app')
javascript
<!-- AnyComponent.vue --> <script setup> import { inject } from 'vue' const apiUrl = inject('apiUrl') const appName = inject('appName') console.log(apiUrl) // 'https://api.example.com' console.log(appName) // 'Мій додаток' </script>

provide/inject проти пропсів

Коли використовувати пропси

javascript
<!-- Прямий батьківсько-дитячий зв'язок --> <ChildComponent :title="title" :count="count" />

Використовуйте пропси, коли:

  • Компоненти безпосередньо пов'язані
  • Потрібен явний зв'язок даних
  • Проста ієрархія (1-2 рівні)

Коли використовувати provide/inject

javascript
<!-- Глибока ієрархія --> <GrandParent> <Parent> <Child> <DeepChild /> <!-- Потрібні дані з GrandParent --> </Child> </Parent> </GrandParent>

Використовуйте provide/inject, коли:

  • Глибока ієрархія компонентів
  • Багато проміжних компонентів
  • Глобальний контекст (тема, локаль, API)

Загальні помилки

Передача не реактивного значення

javascript
<!-- Неправильно --> <script setup> import { provide, ref } from 'vue' const count = ref(0) provide('count', count.value) // Передає лише значення, а не ref! </script> <!-- Правильно --> <script setup> import { provide, ref } from 'vue' const count = ref(0) provide('count', count) // Передає ref </script>

Мутація даних у дочірньому компоненті

javascript
<!-- Неправильно --> <script setup> import { inject } from 'vue' const theme = inject('theme') // Не рекомендується змінювати безпосередньо theme.value = 'dark' </script> <!-- Правильно - передайте функцію для модифікації --> <script setup> import { inject } from 'vue' const theme = inject('theme') const setTheme = inject('setTheme') setTheme('dark') </script>

Висновок

provide/inject:

  • Передає дані через ієрархію без пропсів
  • Вирішує проблему пробивання пропсів
  • Підтримує реактивність
  • Може використовувати Symbol для ключів
  • Підходить для глобального стану (тема, локаль)
  • Не замінює Vuex/Pinia для складного управління станом

На співбесідах:

Важливо вміти:

  • Пояснити, що таке provide/inject і чому це потрібно
  • Описати проблему пробивання пропсів
  • Показати, як працює реактивність з provide/inject
  • Пояснити різницю між provide/inject та пропсами
  • Навести приклади використання (тема, API клієнт)

Зміст

Що таке provide/inject?Основне використанняComposition APIРеактивністьПередача реактивних данихПередача функцій для модифікаціїЗначення за замовчуваннямСимвольні ключіprovide/inject на рівні застосункуprovide/inject проти пропсівКоли використовувати пропсиКоли використовувати provide/injectЗагальні помилкиПередача не реактивного значенняМутація даних у дочірньому компонентіВисновок

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань