Reputation: 375
I would like to provide reactive objects as readonly like below.
// parent component
const test = ref({ test: 'test' })
provide('test', readonly(test))
Then I thought that should be readonly when I inject it.
// child component
const test = inject('test')
test.value = 'changed!' // should be error
But Actually it doesn't be error. This code doesn't show any error message on browser.
Are there any ways to provide a reactive object which is readonly on the child component ?
If someone knows this solution, please give us the answer.
------ additional information----------- I also try this code in this document. https://vuejs.org/api/reactivity-core.html#readonly This says like below, and actually my Veture warned it on VScode, but it was counted up.
// mutating the copy will fail and result in a warning
copy.count++ // warning!
That link is document of Vue, but I'm usisng '@nuxtjs/composition-api' , is this might be a reason...?
I also checke this article this article. But still I was able to change the injected object in child component.
Upvotes: 1
Views: 634
Reputation: 136
There are a few things wrong with your approach. First, you should use reactive() instead of ref() when creating a reactive object. Secondly, when you are injecting the object, you should access the value by specifying the right key. In your case, the key is 'test'.
test.test = 'changed!'
By doing so, there still is no error, however the initial value remains the same. This is because readonly() returns a special kind of proxy object, which returns a value that remains unaffected by the assignment above.
test.test = 'changed!'
console.log(test.test) // prints 'test'
Additional notes:
Your code could be improved by destructing the injected object
const { test } = inject('test')
test= 'changed!' // Uncaught TypeError: Assignment to constant variable.
You can follow the same pattern with larger objects
const largerObject = {first: 'value 1', second: 'value 2', third: 'value 3'}
const {first, second, third } = largerObject
console.log(first === 'value 1') // true
console.log(second === 'value 2') // true
console.log(third === 'value 3') // true
You should also avoid using the same string for the object name, its key and the value assigned to it as it makes debugging harder. For example, you could write:
const food = reactive({ ingredient: 'sauce' })
Upvotes: 1