Dependency Injection with Vue 3
Tags: vue, javascript
Published: 2021-04-05 09:24:10

# Introduction 

In this article we will be learning how to use Vue's provide and inject.

# Installation

Open your terminal and create a fresh Vue project,

```bash
$ vue create vue-3-dependency-injection
```

Then open the scaffolded project by the CLI in your IDE.

```bash
$ cd vue-3-dependency-injection && code .
```

# Provide

As an example, let's say our client wants to have the user's name in many places in our application. But there are many ways to do that, but the team decided to only go with `provide()` so it can supply data to components.

*Note: The example scenario may not be so ideal but just to demo how `provide()` and `inject()` works*

```html
<template>
  <AppFirstChild />
  <AppSecondChild />
  <AppThirdChild />
</template>

<script>
import { defineComponent, provide } from "@vue/runtime-core";
import AppFirstChild from "./components/AppFirstChild.vue";
import AppSecondChild from "./components/AppSecondChild.vue";
import AppThirdChild from "./components/AppThirdChild.vue";

export default defineComponent({
  name: "App",

  components: {
    AppFirstChild,
    AppSecondChild,
    AppThirdChild,
  },

  setup() {
    provide("user", "Carlo Miguel Dy");
  },
});
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
```

But we can just use props instead? We can definitely pass down props from Parent to child component and this child component passes down this prop to its other child components, and when that child component also has its own child components that needs the data from the root component you pass down props as well. 

Actually this is a problem and things might not be that consistent across our application. So the solution to that problem is to use dependency injection with `provide()` and have all the nested child components use `inject()` to get the provided data.

# Inject Dependency

The one way we can use or get the value from `provide()` is to use `inject()`. We'll import that also from `@vue/runtime-core`. Now let us inject the provided data from our Parent component.

For component `AppFirstChild`

```html
<template>
  <h1>{{ user }}</h1>

  <AppFirstChildChild />
</template>

<script>
import { defineComponent, inject } from "vue";
import AppFirstChildChild from "./AppFirstChildChild.vue";

export default defineComponent({
  components: {
    AppFirstChildChild,
  },

  setup() {
    const user = inject("user");

    return {
      user,
    };
  },
});
</script>
```

As you see `AppFirstChild` component also has a child component. We can also use `inject()` to get the data provided from the root Parent component easily.

for component `AppFirstChildChild`

```html
<template>
  <h1>AppFirstChildChild: {{ user }}</h1>
</template>

<script>
import { defineComponent, inject } from "vue";

export default defineComponent({
  setup() {
    const user = inject("user");

    return {
      user,
    };
  },
});
</script>
```

# Provide any data

We are not only limited to provide values as string, we can pass down any type of data. It can be an array, a number, or an object. 

So let us provide another data with emojis

```ts
export default defineComponent({
  name: "App",

  components: {
    AppFirstChild,
    AppSecondChild,
    AppThirdChild,
  },

  setup() {
    provide("user", "Carlo Miguel Dy");
    provide("emojis", {
      fire: "🔥",
      star: "⭐",
      pizza: "🍕",
    });
  },
});
```

# Demo

Our client is happy with the functionality that we created, cheers!

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7yle3ewwhx1iavk7sfcg.png) 

# Conclusion

When we want to be consistent in passing down values to other child components across our entire application, we should use `provide()` and `inject()` instead as it saves us the time and all the frustrations when just using props.

Thanks for taking the time to read, hope you had a wonderful weekend!