Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error Unexpected mutation of "todo" prop in vue.js (I'm using vue3)

Tags:

vue.js

I'm making a todo app in vue.js which has a component TodoItem

<template>
  <div class="todo-item" v-bind:class="{'is-completed':todo.completed}">
    <p>
      <input type="checkbox" @change="markCompleted" />
      {{todo.task}}
      <button class="del">x</button>
    </p>
  </div>
</template>

<script>
export default {
  name: "TodoItem",
  props: ["todo"],
  methods: {
    markCompleted() {
      this.todo.completed = true
    },
  },
};
</script>

todo prop that I'm passing:

{
  id:1,
  task:'todo 1',
  completed:false
}

but it is throwing an error error Unexpected mutation of "todo" prop

like image 633
Omama Zainab Avatar asked Sep 01 '20 13:09

Omama Zainab


People also ask

How to pass props from one component to another in Vue?

Method 1 (Vue 2.3.0+) – From your parent component, you can pass prop with sync modifier Method 2 – Pass props from parent component without sync modifier and emit an event when the value changed. For this method, everything else is similar as well. Just need to emit an event when the todo item changed to completed. The code is untested.

How to create form and todo list in VUE 3?

Create new Vue 3 project with Vue CLI. 2. Create form and todo list in App.vue. 3. Import ref package. Takes an inner value and returns a reactive and mutable ref object. 4. The setup function is a new component option. Create setup function. 5. Create all property and methods. Also we use localStorage for data saving. That's it.

How to pass props from parent component without sync modifier?

Method 2 – Pass props from parent component without sync modifier and emit an event when the value changed. For this method, everything else is similar as well. Just need to emit an event when the todo item changed to completed. The code is untested. Apologies if anything does not work.

How to have the child component update Todo when the parent updates?

All props form a one -way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. If you wish to have the child component update todo.completed, you have two choices: This approach will require a bit of change to your props.


1 Answers

Method 1 (Vue 2.3.0+) - From your parent component, you can pass prop with sync modifier

Parent Component

<TodoItem v-for="todo in todoList" :key="todo.id" todo_prop.sync="todo">

Child Component

    <template>
      <div class="todo-item" v-bind:class="{'is-completed':todo.completed}">
        <p>
          <input type="checkbox" @change="markCompleted" />
          {{todo.task}}
          <button class="del">x</button>
        </p>
      </div>
    </template>
    
    <script>
    export default {
      name: "TodoItem",
      props: ["todo_prop"],
      data() {
         return {
            todo: this.todo_prop
         }
      },
      methods: {
        markCompleted() {
          this.todo.completed = true
        },
      },
    };
    </script>

Method 2 - Pass props from parent component without sync modifier and emit an event when the value changed. For this method, everything else is similar as well. Just need to emit an event when the todo item changed to completed.

The code is untested. Apologies if anything does not work.

like image 151
Tharavink Prasad Sivarajan Avatar answered Sep 24 '22 23:09

Tharavink Prasad Sivarajan