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) }
}
}
}
To handle dependency injection in Vue, the provide and inject options are provided out of the box.
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.
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With