[Vuejs]-Can't set object property as reactive in Vue.js

4👍

The issue is with your property name. Change the ‘todo-item’ in the data section to todoItem.

This works

<template>
    <div>
        <button @click.prevent="printPerson">Print Person</button>
        <br />
        <button @click.prevent="deletePerson">Delete Person</button>
    </div>
</template>

<script>
    export default {
        data: () => ({
            todoItem: {
                id: 1,
                text: 'Buy tickets',
                isDone: false,
                person: 'Boss',
                location: 'Boryspil',
                childTask: null,
            },

        }),
        computed: {
            hasLocation() {
                return this.todoItem.location;
            },
            hasPerson() {
                return this.todoItem.person;
            },
            hasChildTask() {
                return this.todoItem.childTask;
            },
            hasParentTask() {
                return true;
            },
        },

        methods: {
            deletePerson() {
                this.$set(this.todoItem, 'person', null);
                // this.todoItem.person = "null"
                console.log(this.hasPerson);
                console.log(this.todoItem.person);
            },
            printPerson() {
                console.log(this.hasPerson);
                console.log(this.todoItem.person);
            }
        }
    }
</script>

Also, using "this.todoItem.person = null" works.

If still doesn’t work for you, edit your question and add the complete component code and we can help.

👤MAW

0👍

My problem was in props, I get todoItem from parent element, and I can’t do it reactive, but with deep watch all object properties becomes reactive.
I solved my problem just adding watch property to my component:

And now when I change person (or any other) property of my todoItem changes updates in computed properties either.

    watch:{
        todoItem:{
            deep: true,
            handler(){
                this.saveTodoAction(this.todoItem);
            }
        }
    },

And this is the whole code:

import HoveredChip from "@/components/HoveredChip";
import {mapMutations, mapActions} from 'vuex';
export default {
    name: "TodoItem",
    components: {HoveredChip},
    props:['todo-item'],
    data() {
        return{
            isActive : true,
        }
    },
    computed:{

        hasLocation(){
            return this.todoItem.location;
        },
        hasPerson(){
            return this.todoItem.person;
        },
        hasChildTask(){
            return this.todoItem.childTask;
        },
        hasParentTask(){
            return true;
        },
        people(){
            return [
                "Dad",
                "Ann",
                "Boss",
                "Prostitute"
            ]
        },
        places(){
            return []
        }
    },
    methods:{
        ...mapMutations(['addPersonMutation'],{

        }),
        ...mapActions(['saveTodoAction']),
        moveToPerson(){

        },
        moveToLocation(){

        },
        moveToPatentTask(){

        },
        addLocation(){

        },
        addPerson(val){
            this.addPersonMutation(val);
        },

        addChildTask(){

        },
        deletePerson(){
            this.todoItem.person = null;
        },
        deleteLocation(){

        },
        deleteChildTask(){

        },
        editLocation(){

        },
        savePerson(){

        },
        editChildTask(){

        },

    },
    watch:{
        todoItem:{
            deep: true,
            handler(){
                this.saveTodoAction(this.todoItem);
            }
        }
    },
    created(){
    }
}

Leave a comment