Home  >  Q&A  >  body text

Task properties in Vue.js changed unexpectedly in to-do list app

<p>I have a store that contains states, changes, getters, etc. The status contains the following list of tasks. </p> <pre class="brush:php;toolbar:false;">const state = { tasks:[{ title: "Get up", completed: false }, { title: "Project 2", completed: false }, ] }</pre> <p><code>Todo.vue</code></p> <pre class="brush:php;toolbar:false;"><template> <Task v-for="(task,key) in tasks" :id="key" :task="task" :key="key" /> </template> <script> import { defineComponent } from 'vue'; import Task from '../components/Task.vue' import {mapGetters} from 'vuex' export default defineComponent({ name: 'PageIndex', components:{ Task }, computed:{ ...mapGetters('task', ['tasks']) //Get tasks from the task module }, }) </script></pre> <p><code>task.vue</code></p> <pre class="brush:php;toolbar:false;"><template> <q-item clickable :class="!task.completed ? 'bg-orange-1' : 'bg-green-1'" v-ripple> <q-item-section side top> <q-checkbox v-model="task.completed" /> //////////////// The problem lies in this line </q-item-section> <q-item-section> <q-item-label :class="{'text-strikethrough' : task.completed}">{{task.name}}</q-item-label> </q-item-section> </q-item> </template> <script> import {mapActions} from 'vuex' export default { props: ["task"], } </script></pre> <p>In the above code, in Task.vue</p> <pre class="brush:php;toolbar:false;"><q-checkbox v-model="task.completed" /></pre> <p>The problem is in this line. If I remove <code>v-model="task.completed"</code> from the code given above then everything works fine otherwise it throws an error with the message <code>Unexpected mutation of "task" prop</code></p>
P粉966979765P粉966979765420 days ago409

reply all(1)I'll reply

  • P粉057869348

    P粉0578693482023-08-27 09:34:46

    The problem is that you are trying to change a prop and the corresponding vuex state outside of the mutation. Passing a value to the v-model directive will create a two-way data binding. Your task prop refers to an object in the state. When q-checkbox changes the value of task.completed, the object is updated directly in the state. Instead, you should create a mutation that updates your task:

    export const mutations = {
      updateTask(state, payload){
        const task = state.tasks.find(t => t.id === payload.id);
    
        if(task) Object.assign(task, payload)
      }
    }
    

    Then you can use this mutation

    in the template
    <q-checkbox :value="task.completed" @input="updateTask({id: task.id, completed: !task.completed})" />
    

    Also note that the actual prop and event names of the q-checkbox component may vary depending on how you implement it

    reply
    0
  • Cancelreply