Vue 3 Provide & Inject — Amazing Prop Alternative

Mustafa Çağrı Güven
3 min readApr 14, 2024

--

In a Vue component hierarchy, envision a depth of five levels. You encounter the common dilemma of transmitting data from the grandparent to the grandchild. The conventional remedy? Laboriously funneling the data down the chain via props. But behold, Vue 3 unveils a revolutionary alternative: provide and inject!

In Vue’s lexicon, provide facilitates data sharing, while inject retrieves it. It’s a refreshing departure from the rigmarole of prop-based data transfer.

Utilizing Provide / Inject in Setup To wield provide(), integrate it within setup() during component initialization for seamless operation.

Here is a simple definition from w3school:

In Vue, Provide/Inject is a mechanism employed to furnish data from one component to others, especially in extensive projects. Provide enables the availability of data to other components, while Inject facilitates the retrieval of this provided data. It serves as an alternative method for data sharing, diverging from the conventional practice of passing data through props.

Employing Provide / Inject within Setup

To employ provide(), embed it within the setup section, as it demands synchronous invocation during the component’s setup() phase.

How can we use provide?

provide(‘myVariable’, ‘theValue’)

Isn’t it elegantly simple? provide() accepts two arguments: a key (usually a string) and its corresponding value, which could be of any type: string, number, object, or array.

Navigating Real-World Complexity

Consider a scenario from one of my latest projects. We retrieve a string data template from an API. Imagine components like Form.vue, MyComponent.vue, and AnotherComponent.vue require this data. However, v-html proves impractical for rendering within this structural context.

Form.vue

<MyComponent prop1=”test” :prop2=”theValueOfAComputedVariable” :formErrors=”formErrors”/><AnotherComponent prop1=”test2” :prop2=”theValueOfAComputedVariable2” :formErrors=”formErrors” />

Note: you can use only :formErrors like <AnotherComponent prop1=”test2” :prop2=”theValueOfAComputedVariable2” :formErrors /> and it is another topic to discuss in another post.

As you can guess, we can not use a v-html for this structure so we need to use something else. Therefore, we are using a 3rd party package for vue3-runtime-template. It is actually just rendering the data that we provide for the component that’s all.

Buuuut, we need to transfer formErrors always with the components and if the component numbers increase, this will make it hell for us. So, what can we do to make it easier?

We can define a provide (formErros) in the Form.vue and we can inject the children components (AnotherComponent.vue and MyComponent.vue)

Form.vue

provide(‘executeValidations2’, executeValidations3)

MyComponent.vue

executeValidations = inject(‘executeValidations2’)

Now, the executeValidations is a reactive variable and you can use executeValidations.value in the setup and executeValidations in the template.

Voilà! Now, executeValidations becomes reactive, accessible within both setup() and template sections. Child components wield the power to manipulate this data as needed, ensuring dynamic responsiveness to evolving requirements.

  watch(
executeValidations,
async () => {
try {
if (executeValidations.value[props.name]) {
await validate()
console.info('187 validate')
executedValidations.value[props.name] = true
}
} catch (error) {
console.error('error catch', error)
}
},
{ immediate: true },
)

In essence, Vue 3's Provide & Inject mechanism streamlines data sharing, liberating us from the shackles of prop-driven data transmission. Embrace its simplicity and watch your Vue applications thrive in a more interconnected ecosystem.

For extra information, you may check these sources as well:

In conclusion, Vue 3’s Provide & Inject feature represents a significant advancement in data management within Vue applications. By offering a seamless alternative to prop-based data passing, it streamlines the process of sharing data across component boundaries. This not only enhances code readability and maintainability but also fosters a more flexible and scalable architecture, particularly in large-scale projects. What are your thoughts on this approach to data sharing in Vue? Do you see it as a valuable addition to your Vue development toolkit? Please do not hesitate to share your opinions.

--

--

Mustafa Çağrı Güven
Mustafa Çağrı Güven

Written by Mustafa Çağrı Güven

Comp. Eng. @Sabancı University Graduated '11 / Senior Frontend Wizard / Vue.js 3 / Node.js / Express.js / MEVN / Nuxt 3 / Clean Code & Open Source ❤

No responses yet