SoFunction
Updated on 2025-04-11

Analyze the use of provide and inject of vue and its principles

First, let’s talk about why we use provide/inject? For communication between grandpa and grandchild components, or even grandpa components and grandchild components, we use vuex to communicate.

That's true, but please listen to me, but sometimes your project is smaller or even has few scenarios for component communication. So is it a waste to introduce vuex just for a few communication parameters? Some people may also think of using it$parentGet the parent component instance to get data/methods. This kind of two layers is fine. But if there are multiple layers, and the components are very nested deeply, how do you do it? Write a function$parentEncapsulate it again. Isn’t that very troublesome? You don’t have to save the country in a straightforward way. Haha~ It's a long way to go.

I don’t talk so much nonsense, so I will tell you that using provide/inject is to solve your problems, which is absolutely correct. Let's see how to use it? Backhand is a few lines of simple code:

1.The parent component provides the parameters to be passed to the child component
provide() {
    return {
      listType: ,
    }
  }
2.Subcomponent usage:
inject: ['listType'],

Of course, you can also specify your default value and the source of your parameters in inject:

inject:{
  listType:{
  from:"par"//Provide defined name  default:1
  }
}

OK! Isn't it very simple? In fact, whether it is a parent component or an ancestor component, you can inject dependencies into descendant components, no matter how deep the component is.

Let me say something more:

Provide can be an object or a function that returns an object.

inejct: can be a string array or an object.

If you are interested, take a look at the source code section below, which is quite easy to understand:

The core source code of the provide:

export function provide<T>(key: InjectionKey<T> | string | number, value: T) {
  if (!currentInstance) {
    if (__DEV__) {
      warn(`provide() can only be used inside setup().`)
    
    }
  } else {
    //Get the current component's providers, the default instance inherits the parent class's providers object    let provides = 
    //Create your own provider object using the parent provider object as a prototype    const parentProvides =
       && 
    if (parentProvides === provides) {
      provides =  = (parentProvides)
    }
    provides[key as string] = value
  }
}
​

The core source code of inject:

export function inject(
  key: InjectionKey<any> | string,
  defaultValue?: unknown,
  treatDefaultAsFactory = false
) {
  //Get the current component instance  const instance = currentInstance || currentRenderingInstance
  if (instance) {
  //Get the providers    const provides =
       == null
        ?  && 
        : 
​
    if (provides && (key as string | symbol) in provides) {
      //If the key exists, return it directly      return provides[key as string]
    } else if ( > 1) {
      //If the key does not exist, the default value will be directly returned to the default value after setting the default value.      return treatDefaultAsFactory && isFunction(defaultValue)
        ? ()
        : defaultValue
    } else if (__DEV__) {
      //If there is no, please prompt      warn(`injection "${String(key)}" not found.`)
    }
  } else if (__DEV__) {
    warn(`inject() can only be used inside setup() or functional components.`)
  }
}
​

This is the article about analyzing the use of vue provider and inject and its principles. For more related content on vue provide and inject, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!