Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make Vue 2 Provide / Inject API reactive?

Tags:

vue.js

vuejs2

I set up my code as follows, and I was able to update checkout_info in App.vue from the setter in SomeComponent.vue, but the getter in SomeComponent.vue is not reactive.

// 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) }
        }
    }
}
like image 609
Mysterywood Avatar asked Jan 14 '21 12:01

Mysterywood


People also ask

Does Vue have dependency injection?

To handle dependency injection in Vue, the provide and inject options are provided out of the box.

How do you make provide and inject reactive?

Vue 2 offered the Provide/Inject API and now it's been enhanced and improved in Vue 3. To make the data reactive, start by using the provide option as a function. Then, wrap your data inside a computed() function to make it reactive and read-only.

How do you use provide and inject in Vue?

The first argument is called the injection key, which can be a string or a Symbol . The injection key is used by descendent components to lookup the desired value to inject. A single component can call provide() multiple times with different injection keys to provide different values.


Video Answer


2 Answers

I found the answer after many hours of searching. You have to use Object.defineProperty to make it reactive. I'm not sure if this is the best approach, but this is a working example.

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,
        }
    }
}

You can later access it via this.appData.checkout_info

like image 199
Mysterywood Avatar answered Nov 15 '22 06:11

Mysterywood


This note from official documentation.

Note: the provide and inject bindings are NOT reactive. This is intentional. However, if you pass down an observed object, properties on that object do remain reactive.

I think this is the answer to your question.

source: https://v2.vuejs.org/v2/api/#provide-inject

like image 23
Anton Avatar answered Nov 15 '22 08:11

Anton