👋 welcome to comment, like, collect oh ~ 😗 if there is wrong place, welcome to correct oh ~

What is provide/inject

Before entering the main body, I would like to tell a true story, which I read many years ago. Although I have forgotten the name of the story, the hero and the background, it does not affect me to state it here 😜😜😜

The story goes like this: The Z family has a very prominent position in The UK, and there are a large number of talented people in the family. There is a rule in the family that everyone should leave a word for the offspring, no matter how long it is, whether it is right or wrong, as long as it is a sincere feeling, the precipitation of this life can be. In their family, there is a long corridor, hung with ancestors left behind the life maxims, these words are precious spiritual wealth, so passed down from generation to generation, influenced by generations of descendants.

Speaking of which, the Z family can be likened to the Vue component tree, and each person who stays can be likened to the provide, whose descendants can be accessed. Provide is equivalent to a data provider, and its descendants have access to the data. When the descendants access the data, they obtain the inject API. Note that provide and inject must be applied in a tree, that is, look back from the node of inject. You need to find the corresponding provide.

Provide /inject Is much more convenient than props to pass values layer by layer from parent to child. It provides data systematically and across layers, provides dependencies, inject dependencies, and interface definitions between components are still clear

  • The parent component does not need to know which child components use the property it provides
  • Child components don’t need to know where inject’s property comes from

Provide /inject responsive data

This is much more powerful than provde/inject in Vue2 because they are not responsive in Vue2,

// App.vue
export default {
    provide() {
        return {
            checkout_info: this.checkout_info,
            updateCheckoutInfo: this.updateCheckoutInfo
        }
    },
    data() {
        return {
            checkout_info:}}, {},methods: {
        updateCheckoutInfo(key, value) {
            this.checkout_info[key] = value
        }
    }
}

// SomeComponent.vue
export default {
    inject: ['checkout_info'.'updateCheckoutInfo']
    computed: {
        deliveryAddress: {
            get() { return this.checkout_info.delivery_address }, // <---- Not reactive
            set(value) { return this.updateCheckoutInfo('delivery_address', value) }
        }
    }
}

Copy the code

To become responsive, object.defineProperty is manually used, and when the getter is triggered, the checkout_info current value is retrieved as follows:

export default {
    data() {
        return {
            checkout_info:}}, {},provide() {
        const appData = {}

        Object.defineProperty(appData, "checkout_info", {
            enumerable: true.get: () = > this.checkout_info,
        })

        return {
            updateCheckoutInfo: this.updateCheckoutInfo,
            appData,
        }
    }
}
Copy the code

Reference:Stackoverflow.com/questions/6…





Vue3 uses the ReActivity API to pass and manipulate responsive data, for example 👀 :

When provide provides responsive data and inject changes this responsive data, the restriction of single data flow in Vue is broken, resulting in unclear data flow and difficult debugging. Think about it, any inject can directly change the data provided, and it becomes very difficult to track changes.

Therefore, it is recommended that all changes to the reactive property be limited to the component that defines provide. That is, provide not only provides the reactive data, but also provides methods to change the reactive property.

For example 👀 :

Reference: V3.vuejs.org/guide/compo…

Besides, make use ofreadonlyIt is also important to wrap responsive data so that it corresponds to responsive objectsread-onlyYes, and stillThe depth ofApplies to each property.

Integrate with the Composition API

We can also use provide/inject in the composite API. Both can only be called during setup() of the current active instance.

For an example, we define a Composable method that contains API requests that provide interfaces in the form of provide to the component tree in which the components are used as inject.

👉 For example, the composition API can be used to maintain business logic in a separate JS file, and the Provide/Inject API can be used to implement state sharing and dependency injection.

Compared with vuex

Provide /inject composition vuex provides provide/inject composition for dependency injection, state sharing, process responsiveness, and logic reuse.

As a simple example, see how provide/inject can replace vuex’s 👀 :

Reference:Vuejsdevelopers.com/2020/10/05/…

I think the most important, is the global singleton pattern vuex, means that all data is global Shared, for example, A component instance a1 and a2 component instances are generated by A component constructor, then the two instance Shared A vuex state, that is to say, the state of the state won’t save the data in the component dimensions. If a component instance is required to maintain a state, you can only manipulate the data as follows:

However, provide/inject can be locally multi-example. Different provide/inject data can be provided to a component tree (distinguished by the first parameter name of provide), and data can be provided to different component trees.

As shown, within the same Vue root instance, provide/ Inject can exist as a local multi-column pattern (one color represents a dependency injection)

Summary 👉 :