harunaga
harunaga

Reputation: 375

Vue / Nuxt providing readonly Object desen't work

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

Answers (1)

3tw
3tw

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

Related Questions