Search code examples
vuejs3

Vue 3: writable computed array not working as expected


In my app I have a simple store that just is a reactive object with readonly access. If I want to update a value in the store I have functions to do it. This way I can prevent to accidentally update a store value. I usually use this with a writable computed property in the component. This works fine for "primitive" types like, string, number and boolean. But when I try to use it with an array I get an error that the array is readonly. Which is technically true, but that's why I have a writeable computed, so it can read the value and when it changes it a method in the store is called.

Here is a playground to showcase the issue: Vue SFC Playground

You can add languages with the plus button once you enter a value in the input field. You can remove existing ones with the minus. But if you try to change a value of an existing one there is an error: [Vue warn] Set operation on key "0" failed: target is readonly. To prove that it works for strings, you can change the language on the dropdown and it is updated in the store.

Is this the expected behavior or am I missing something?


Solution

  • It's strange that you expect to modify the array directly since you try to avoid in the first place with the readonly public state. Just add a method for updating:

    Playground

        public updateLanguage(index: number, language: string){
            this.state.languages[index] = language;
        }
    
    <input type="text" :value="languages[index]" @input="(e: InputEvent) => store.updateLanguage(index, (e.target as HTMLInputElement).value)">