Why do I get this error:
Error [vuex] Do not mutate vuex store state outside mutation handlers.
What does it mean?
It happens when I try to type in the edit input file.
pages/todos/index.vue
<template> <ul> <li v-for="todo in todos"> <input type="checkbox" :checked="todo.done" v-on:change="toggle(todo)"> <span :class="{ done: todo.done }">{{ todo.text }}</span> <button class="destroy" v-on:click="remove(todo)">delete</button> <input class="edit" type="text" v-model="todo.text" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)"> </li> <li><input placeholder="What needs to be done?" autofocus v-model="todo" v-on:keyup.enter="add"></li> </ul> </template> <script> import { mapMutations } from 'vuex' export default { data () { return { todo: '', editedTodo: null } }, head () { return { title: this.$route.params.slug || 'all', titleTemplate: 'Nuxt TodoMVC : %s todos' } }, fetch ({ store }) { store.commit('todos/add', 'Hello World') }, computed: { todos () { // console.log(this) return this.$store.state.todos.list } }, methods: { add (e) { var value = this.todo && this.todo.trim() if (value) { this.$store.commit('todos/add', value) this.todo = '' } }, toggle (todo) { this.$store.commit('todos/toggle', todo) }, remove (todo) { this.$store.commit('todos/remove', todo) }, doneEdit (todo) { this.editedTodo = null todo.text = todo.text.trim() if (!todo.text) { this.$store.commit('todos/remove', todo) } }, cancelEdit (todo) { this.editedTodo = null todo.text = this.beforeEditCache }, }, directives: { 'todo-focus' (el, binding) { if (binding.value) { el.focus() } } }, } </script> <style> .done { text-decoration: line-through; } </style>
stores/todos.js
export const state = () => ({ list: [] }) export const mutations = { add (state, text) { state.list.push({ text: text, done: false }) }, remove (state, todo) { state.list.splice(state.list.indexOf(todo), 1) }, toggle (state, todo) { todo.done = !todo.done } }
Any ideas how I can fix this?
Error: [vuex] do not mutate vuex store state outside mutation handlers. The error means what it says. The solution is to mutate the store only with actions/mutations. You shallowly copy the array so it becomes a part of the store, then you continue to mutate it.
In strict mode, whenever Vuex state is mutated outside of mutation handlers, an error will be thrown. This ensures that all state mutations can be explicitly tracked by debugging tools.
In Vuex, mutations are synchronous transactions: store.
Mutations are intended to receive input only via their payload and to not produce side effects elsewhere. While actions get a full context to work with, mutations only have the state and the payload .
It could be a bit tricky to use v-model on a piece of state that belongs to Vuex.
and you have used v-model
on todo.text
here:
<input class="edit" type="text" v-model="todo.text" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">
use :value
to read value and v-on:input
or v-on:change
to execute a method that perform the mutation inside an explicit Vuex mutation handler
This issue is handled here: https://vuex.vuejs.org/en/forms.html
Hello I have get the same problem and solve it with clone my object using one of the following:
{ ...obj} //spread syntax Object.assign({}, obj) JSON.parse(JSON.stringify(obj))
For your code I think you need to replace this part
computed: { todos () { // console.log(this) return this.$store.state.todos.list } }
With this
computed: { todos () { // console.log(this) return {...this.$store.state.todos.list} } }
I don't make sure if this is the best way but hope this helpful for other people that have the same issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With